시프트 레지스터 사용방법 (Shift Register, 74HC595, 74HC165)

LED 하나를 켜기 위해서 아두이노 디지털 핀 하나를 사용합니다. 하지만 LED가 8개 라면? 디지털 핀 8개 사용하면 됩니다. 하지만 16개 혹은 그 이상이 된다면? 이처럼 사용해야 할 디지털 출력의 수가 많을 때 “시프트 레지스터(shift register)”를 사용하게 됩니다.

시프트 레지스터는 다른 이름으로 Serial to Parallel Converter 로 불립니다. 시리얼(직렬)로 입력되는 데이터를 패러럴(병렬)로 바꿔준다는 얘기입니다. 이걸 보기 편하게 이미지로 나타내면 아래와 같습니다.

BasicShiftRegister

시프트 레지스터에게 데이터가 전달된다고 알려주는 클럭(clock) 신호와 함께 8개의 핀 출력이 어떻게 되는지 알려주는 시리얼 데이터를 일렬로 보내줍니다. 첫 번째 핀만 on 시키고 싶다면 [1000 0000] 신호를 보내면 되겠죠. 그러면 시프트 레지스터는 8개의 신호를 받아 8개의 핀을 신호에 맞게 출력해줍니다. 이런 방식으로 사용하면 그림처럼 2 개의 핀으로 8개 혹은 그 이상의 핀을 제어할 수 있습니다. (실제로는 제어선 3개를 사용합니다.)

LED 출력 뿐 아니라 수십개의 버튼 입력을 받을 때도 시프트 레지스터를 사용할 수 있습니다. 버튼 입력을 받을 때는 동작이 반대로 되겠죠. 그래서 시프트 레지스터는 두 개로 나뉩니다. SIPO(Serial In Parallel Out) 방식과 PISO(Parallel In Serial Out) 방식입니다.

전자는 LED 8 개 혹은 그 이상의 출력을 한 번에 제어할 수 있고 74HC595 칩을 사용합니다.

74hc595n-dscn3898

후자는 버튼 8 개 이상의 입력을 받을 수 있고 74HC165 칩을 사용하면 됩니다.

74HC165-IMG_0690

먼저 74HC595 칩을 이용해서 LED 8개를 제어하는 예제부터 테스트 하겠습니다.

SIPO – 74HC595 핀 구조 및 동작

먼저 74HC595N 칩이 가진 16개의 핀이 어떤 핀인지부터 알아야 합니다.

74HC595-pinout

  • 1~7, 15 (Q0~Q7)
    출력을 제어하고 싶은 8개의 핀입니다. LED 를 제어하고 싶다면 Q0~Q7까지 순서대로 연결해야 합니다.
  • 14 (DS, Data pin)
    클럭 신호에 맞춰 데이터가 전송되는 핀입니다.
  • 13 (OE, Output Enable)
    출력 핀 전체를 한번에 on/off 시키고 싶을 때 사용합니다. 이 핀을 PWM 핀에 연결해주고 PWM 신호를 주면 LED 밝기 조절이 가능합니다. 이 핀은 active low 상태로 사용하기 때문에 굳이 사용치 않을 때는 아두이노 GND 핀에 연결해주면 됩니다.
  • 12 (STcp, Storage(Latch) Register Clock pin)
    시프트 레지스터가 수신한 데이터를 래치 레지스터(Latch register, 핀 제어값 저장공간)에 저장하도록 해주는 신호선
  • 11 (SHcp, Shift Register Clock pin)
    아두이노와 시프트 레지스터가 박자에 맞춰 데이터를 전송할 수 있도록 클럭 신호를 전송하는 핀입니다.
  • 10 (MR, Master Re-clear)
    리셋핀, Active low 이므로 반대로 5V에 연결합니다.

11(SHcp) 핀에 의해 클럭 신호가 생성되면 이 신호에 맞춰 14(DS) 핀으로 8개의 데이터를 전송합니다. 즉, 클럭 신호가 HIGH 상태일 때 DS 핀의 신호도 HIGH 라면 1 이 전송된 것이고, 클럭 신호가 HIGH 일 때 DS 핀의 신호가 LOW 라면 0 이 전송된 것입니다.

이렇게 8개의 신호가 전달되면 시프트 레지스터는 수신한 값을 Storage(Latch) register 라는 저장공간에 넣습니다. 이후에는 Storage(Latch) register 에 저장된 값에 따라 8개의 Q0~Q7 출력이 변화하게 됩니다.

이때, Storage(Latch) register 값을 외부에서 변경한다는 신호도 보내줘야만 레지스터 값이 바뀝니다. 그래서 데이터를 전달하기 전에 12(STcp) – latch 핀을 LOW 상태로 바꿔주고 데이터 전송이 끝났을 때 HIGH 상태로 다시 돌려둡니다.

learn_arduino_shift_register

연결 방법

조금 복잡하지만 아래 순서로 연결합니다. 먼저 아두이노 5V, GND 핀을 브레드보드에 연결한 다음 74HC595 칩에 연결합니다.

  • 16 (VCC) –> 5V
  • 10 (MR) –> 5V
  • 8 (GND) –> GND
  • 13 (OE) –> GND

이제 3개의 데이터, 클럭, latch 클럭 핀을 아두이노의 디지털 핀 3개에 연결합니다. (변경 가능)

  • 11 (SHcp, clock) –> D12
  • 12 (STcp, latch clock) –> D8
  • 14 (DS, data) –> D11

여기에 8개의 저항을 이용해서 Q0~ Q7 까지 LED를 연결해주면 됩니다.

ShftOutExmp1_3

(위 그림에서 12(STcp) – GND 사이의 1uF 커패시터는 생략해도 될듯?)

스케치

간단한 예제부터 테스트…

/*
Adafruit Arduino - Lesson 4. 8 LEDs and a Shift Register
*/
 
int latchPin = 8;      //Pin connected to ST_CP of 74HC595
int clockPin = 12;   //Pin connected to SH_CP of 74HC595
int dataPin = 11;    //Pin connected to DS of 74HC595
 
byte leds = 0;
 
void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
}
 
void loop() {
  leds = 0;
  updateShiftRegister();
  delay(500);
  for (int i = 0; i < 8; i++)  {
    bitSet(leds, i);
    updateShiftRegister();
    delay(500);
  }
}
 
void updateShiftRegister() {
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}

1 byte 크기의 변수인 leds 를 구성하는 비트대로 8개의 LED 를 on/off 합니다. 스케치에서 leds 값이 다른 방식으로 변경되도록 응용해서 사용해보세요.

스케치에서 가장 중요한 부분은 아래 코드입니다. 실제 시프트 레지스터를 제어하는 부분입니다.

void updateShiftRegister() {
   digitalWrite(latchPin, LOW);
   shiftOut(dataPin, clockPin, LSBFIRST, leds);
   digitalWrite(latchPin, HIGH);
}

먼저 데이터를 시프트 레지스터로 전송하기 전에 Storage register clock pin (latch pin) 의 상태를 LOW 로 바꿔줘야 합니다. 데이터 전송이 끝나면 다시 HIGH로 바꿉니다.

데이터를 전송할 때는 아두이노가 제공하는 shiftOut() 함수를 사용하면 됩니다. shiftOut() 함수는 4개의 값을 넣어줘야 하는데 순서대로 아래와 같은 의미입니다.

  • dataPin : DS 핀 넘버
  • clockPin : Clock 핀 넘버
  • LSBFIRST : LSB(Least Significant Bit) 비트부터 전송. 즉, 1byte 데이터 중 가장 오른쪽의 데이터부터 전송한다는 의미입니다. MSBFIRST (Most Significant Bit) 을 사용해도 됩니다. 이때는 LED on/off 가 반대로 바뀌겠죠
  • leds : 8개의 비트 상태값을 담은 1byte 데이터

스케치를 실행해보면 아래처럼 동작합니다.

20160524_185523

여러개의 시프트 레지스터 연결

2개 이상의 시프트 레지스터를 연결해서 제어가능한 출력의 수를 늘릴 수 있습니다.

이때는 아래처럼 연결됩니다.

ShftOutExmp2_3

2 번째로 추가한 시프트 레지스터 칩도 첫 번째와 유사하게 연결하는데 데이터 전송과 관련된 아래 3 핀을 다르게 연결해주면 됩니다.

  • Shift Register 1 –> Shift Register 2
  • 11 (SHcp, clock) –> 11 (SHcp, clock)
  • 12 (STcp, latch clock) –> 12 (STcp, latch clock)
  • 9 (Q7”, serial out) –> 14 (DS, data)

이렇게 연결하면 여전히 3개의 핀만 아두이노에 연결되지만 16개의 LED를 제어할 수 있습니다. 16개의 LED를 제어할 때에는 아래처럼 latch pin 을 LOW 로 바꾼 후, 데이터를 1byte 씩 두 번 보내면 됩니다.

    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 255);
    shiftOut(dataPin, clockPin, 255);
    digitalWrite(latchPin, 1);

라이브러리

shiftOut() 함수를 이용해 제어하기가 어려운 경우 혹은 7 segment 같은 장치를 좀 더 편하게 제어하고 싶은 경우 라이브러리를 이용하세요.

PISO – 74HC165 시프트 레지스터

SIPO 방식의 74HC595 와 거의 유사한 방식으로 사용이 가능합니다. 아래 링크를 참고하세요.

참고자료

You may also like...