본문 바로가기
MCU/아두이노

아두이노에서 74HC93 / 74HC161 / 74HC163 Binary Counter 사용하기

by linuxgo 2025. 9. 10.

🔎 Binary Counter란?

74HC93, 74HC161, 74HC163은 모두 Binary Counter(이진 카운터) IC입니다.

  • 74HC93 : 4bit Ripple Counter (비동기)

  •  
  • 74HC161 / 74HC163 : 4bit Synchronous Binary Counter (동기식, Load/Enable 지원)

 

이 칩들은 클럭 신호가 들어올 때마다 Q출력 핀에 2진수 형태로 카운트 값을 출력합니다.
간단히 말해, 클럭 펄스를 입력하면 자동으로 2진 카운터가 동작합니다.

⚡ 아두이노와 연결하기

아두이노와 연결 시 필요한 기본 핀은 다음과 같습니다.

  • CLK (Clock) : 아두이노에서 펄스를 발생시켜 카운터 증가
  • RESET : 카운터 값 초기화
  • LOAD : 원하는 값으로 병렬 로드 (74HC161/163 전용)
  • ENABLE : 카운트 동작 허용/정지
  • Q0~Q3 : 카운터 출력값(4bit)

🔌 아두이노와 74HC 계열 Binary Counter 연결 방법

1️⃣ 기본 연결 원리

Binary Counter IC는 클럭(Clock) 입력을 받아 카운트가 증가하고, 그 결과를 Q0~Q3 출력으로 내보냅니다.
아두이노는 다음과 같은 역할을 합니다:

  • Clock 핀 → 아두이노에서 HIGH-LOW 펄스를 만들어 카운트 증가
  • Reset 핀 → 카운터 값을 초기화
  • Enable 핀 → 카운트 동작 허용/정지
  • Load 핀 → 병렬 데이터 로드 (74HC161/163 전용)
  • Q0~Q3 출력핀 → 아두이노에서 읽어서 현재 카운터 값 확인

2️⃣ 74HC161 연결 예시

74HC161 핀 기능 아두이노 핀
CLK 클럭 입력 D2
CLR 리셋(비동기) D3
LOAD 병렬 로드 D4
ENP / ENT Enable 핀 D5
Q0 ~ Q3 카운터 출력 D6, D7, D8, D9
VCC 전원 +5V 5V
GND 접지 GND

👉 Q0~Q3은 아두이노 입력 모드로 설정해 카운트 값을 읽어옵니다.
👉 ENP/ENT 두 개의 Enable 핀은 보통 묶어서 같이 제어하거나, 하나는 GND에 연결하고 하나만 제어합니다.


3️⃣ 74HC93 연결 예시

74HC93 핀 기능 아두이노 핀
CLK A 1분주 카운터 클럭 D2
CLK B 3~4비트 카운터 클럭 Q0 출력에 직접 연결
R0(1),R0(2) 리셋 입력 (두 핀 모두 HIGH일 때 초기화) D3, D4
Q0 ~ Q3 카운터 출력 D6, D7, D8, D9
VCC 전원 +5V 5V
GND 접지 GND

👉 74HC93은 비동기 카운터라서 Q0 출력이 다음 스테이지 클럭 입력으로 연결됩니다.


4️⃣ 74HC163 연결 예시

4HC163 핀 기능 아두이노 핀
CLK 클럭 입력 D2
CLR 리셋 D3
LOAD 병렬 로드 D4
ENP / ENT Enable 핀 D5
Q0 ~ Q3 카운터 출력 D6, D7, D8, D9
VCC 전원 +5V 5V
GND 접지 GND

👉 74HC161과 거의 동일하나, Reset과 Load의 내부 논리 차이가 있으므로 데이터시트를 참고해야 합니다.

🛠 아두이노용 라이브러리 만들기

매번 핀을 직접 제어하기는 불편하니, 전용 라이브러리를 만들었습니다.
HCxCounter 클래스는 74HC93, 74HC161, 74HC163을 공통적으로 다룰 수 있습니다.

라이브러리 파일 구조

HCxCounter/
 ├── HCxCounter.h
 ├── HCxCounter.cpp
 └── examples/
      └── HCxCounter_Test/HCxCounter_Test.ino

HCxCounter.h

#ifndef HCXCOUNTER_H
#define HCXCOUNTER_H

#include <Arduino.h>

/*
 * HCxCounter 클래스
 * 74HC93 / 74HC161 / 74HC163 같은 Binary Counter IC를
 * 아두이노에서 쉽게 제어하기 위한 라이브러리
 *
 * 기능:
 * - Clock 펄스 발생 (카운트 증가)
 * - Reset (카운터 초기화)
 * - Load (병렬 로드, 74HC161/163 전용)
 * - Enable (카운트 허용/정지)
 * - Q 출력핀(4bit) 값 읽기
 */

class HCxCounter {
  public:
    /*
     * 생성자
     * clkPin   : Clock 입력 핀 (필수)
     * resetPin : Reset 입력 핀 (없으면 255)
     * loadPin  : Load 입력 핀 (없으면 255)
     * enablePin: Enable 입력 핀 (없으면 255)
     * qPins    : Q0~Q3 출력 핀 배열 (없으면 nullptr)
     */
    HCxCounter(uint8_t clkPin, 
               uint8_t resetPin = 255, 
               uint8_t loadPin = 255,
               uint8_t enablePin = 255,
               uint8_t qPins[4] = nullptr);

    void begin();               // 핀 모드 초기화
    void pulseClock();          // Clock 펄스 1회 발생 (카운트 +1)
    void reset();               // 카운터 리셋
    void load(uint8_t value);   // 병렬 로드 (74HC161/163 전용, 기본 구현은 Load 핀만 Pulse)
    uint8_t read();             // Q0~Q3 출력값 읽기 (0~15)
    void enable(bool en);       // Enable 핀 제어 (true: 동작, false: 정지)

  private:
    uint8_t _clkPin, _resetPin, _loadPin, _enablePin;
    uint8_t _qPins[4];
};

#endif

HCxCounter.cpp

#include "HCxCounter.h"

HCxCounter::HCxCounter(uint8_t clkPin, uint8_t resetPin, uint8_t loadPin, uint8_t enablePin, uint8_t qPins[4]) {
  _clkPin = clkPin;
  _resetPin = resetPin;
  _loadPin = loadPin;
  _enablePin = enablePin;

  // Q 출력 핀 저장
  if (qPins != nullptr) {
    for (int i = 0; i < 4; i++) _qPins[i] = qPins[i];
  } else {
    for (int i = 0; i < 4; i++) _qPins[i] = 255; // 사용하지 않음
  }
}

void HCxCounter::begin() {
  // 입력 핀/출력 핀 초기화
  pinMode(_clkPin, OUTPUT);
  if (_resetPin != 255) pinMode(_resetPin, OUTPUT);
  if (_loadPin  != 255) pinMode(_loadPin, OUTPUT);
  if (_enablePin != 255) pinMode(_enablePin, OUTPUT);

  for (int i = 0; i < 4; i++) {
    if (_qPins[i] != 255) pinMode(_qPins[i], INPUT);
  }
}

void HCxCounter::pulseClock() {
  // Clock 핀에 HIGH → LOW 펄스를 1회 발생
  digitalWrite(_clkPin, HIGH);
  delayMicroseconds(5);   // 짧은 시간 대기
  digitalWrite(_clkPin, LOW);
  delayMicroseconds(5);
}

void HCxCounter::reset() {
  // Reset 핀을 사용 가능할 때만 실행
  if (_resetPin != 255) {
    /*
     * 주의: IC마다 Reset 신호의 논리가 다름
     * - 74HC93: LOW 레벨에서 Reset 동작
     * - 74HC161/163: HIGH 레벨에서 Reset 동작
     * 필요에 따라 이 부분 수정 가능
     */
    digitalWrite(_resetPin, LOW);   
    delayMicroseconds(5);
    digitalWrite(_resetPin, HIGH);
  }
}

void HCxCounter::load(uint8_t value) {
  // 병렬 Load 기능 (실제 구현은 외부 데이터 핀 연결 필요)
  if (_loadPin == 255) return;

  // 단순히 Load 핀에 Pulse를 줌
  digitalWrite(_loadPin, LOW);
  delayMicroseconds(5);
  digitalWrite(_loadPin, HIGH);
}

uint8_t HCxCounter::read() {
  // Q0~Q3 출력값을 읽어서 4bit 값으로 합치기
  uint8_t val = 0;
  for (int i = 0; i < 4; i++) {
    if (_qPins[i] != 255) val |= (digitalRead(_qPins[i]) << i);
  }
  return val;
}

void HCxCounter::enable(bool en) {
  // Enable 핀이 연결되어 있을 경우 제어
  if (_enablePin != 255) {
    /*
     * 74HC161/163의 경우 Enable이 LOW일 때 동작
     * 따라서 true → LOW, false → HIGH
     */
    digitalWrite(_enablePin, en ? LOW : HIGH); 
  }
}

📘 예제 코드

#include <HCxCounter.h>

// 74HC161 연결 예시
// CLK → 2번핀, RESET → 3번핀, LOAD → 4번핀, ENABLE → 5번핀
// Q0~Q3 → 6,7,8,9번핀
uint8_t qPins[4] = {6,7,8,9};
HCxCounter counter(2, 3, 4, 5, qPins);

void setup() {
  Serial.begin(9600);

  // 핀 모드 설정
  counter.begin();

  // 카운터 초기화
  counter.reset();

  // Enable = true → 카운터 동작 허용
  counter.enable(true);
}

void loop() {
  // Clock 펄스 1회 발생 → 카운터 +1
  counter.pulseClock();

  delay(500); // 0.5초마다 카운트

  // Q0~Q3 출력값 읽기
  uint8_t val = counter.read();

  // 시리얼 모니터에 출력
  Serial.print("Counter 값: ");
  Serial.println(val);
}

📊 실행 결과

아두이노가 0.5초마다 Clock 펄스를 발생시키면,
74HC161의 출력(Q0~Q3)은 0 → 1 → 2 → … → 15 → 0 순으로 증가합니다.

시리얼 모니터에는 다음과 같이 출력됩니다:

Counter: 0
Counter: 1
Counter: 2
...
Counter: 15
Counter: 0

✅ 마무리

이렇게 하면 74HC93 / 74HC161 / 74HC163 같은 Binary Counter IC를 아두이노에서 손쉽게 제어할 수 있습니다.
특히 LED, 주파수 분주, 간단한 타이머 회로 등을 아두이노 없이도 IC로 구현할 수 있으니, 학습용이나 하드웨어 제어용으로 활용해보면 좋습니다.