※ 주의사항 ※
본 블로그는 수업 내용을 바탕으로 제가 이해한 부분을 정리한 블로그입니다.
본 내용을 참고로만 보시고, 틀린 부분이 있다면 지적 부탁드립니다!
감사합니다😁
안녕하세요!!
오늘은 아래와 같은 내용을 확인해보겠습니다.
디지털 출력 확장
74HC595
ATmega128A에는 총 64개의 핀이 있고 여기서 53개의 핀이 디지털 입출력용으로 사용된다.
53비트의 데이터는 넉넉하지 않은 용량으로 한정된 디지털 입출력핀으로 많은 수의 핀을 사용하기 위한 방법은 크게 소프트웨어적인 방법과 하드웨어적인 방법으로 나뉜다.
소프트웨어적인 방법으로는 FND모듈을 사용하는 방법과 같은 잔상효과를 사용하는 방법이 있고, 하드웨어적인 방법으로는 전용 입출력 확장 칩을 사용하는 방법이 있다. 오늘은 하드웨어적인 방법에서도 디지털 출력 확장 칩(74HC595)을 사용해서 1개의 INPUT으로 8개의 OUTPUT을 할 수 있도록 실습 진행.
(디지털 입력 확장 칩(74HC165)은 가지고 있지 않기 때문에 실습을 미실시😥)
1. 74HC595 칩 핀 설명 및 회로도
1-1. 핀 설명
1) 출력 핀 : Q0 ~ Q7(QA ~ QH)
- DS핀으로 통해 들어온 직렬의 8비트 데이터를 병렬 데이터로 바꾸어서 출력한다.
2) 입력 핀 : DS
- 14번 핀인 DS핀을 통해 직렬로 1비트씩 여덟번에 걸쳐 8비트의 데이터를 받는다.(직렬)
3) 전원부 관련 핀 : VCC, GND
4) Shift Clock 핀 : SHCP
- 이동 클록(Shift Clock)은 송신단에서 직렬로 전송하는 데이터를 수신하여 74595칩 내부에서 1비트씩 이동하기 위해 사용된다.
- 즉, 해당핀에 HIGH가 되면 DS핀을 통해 쉬프트 레지스터로 들어온 직렬 데이터의 1비트가 스토리지 레지스터로 이동하고 동시에 다음 쉬프트 레지스터로 이동한다. (자세한 설명과 그림은 동작 과정 설명 참고)
5) Latch Clock 핀 : STCP
- 해당 핀이 HIGH가 되면 스토리지 레지스터에 있는 8개의 데이터가 Q0 ~ Q7핀을 통해 출력된다.
6) Output Enable 핀 : /OE
- 해당 핀이 LOW가 되면 출력단의 래치를 활성화 시켜 출력이 가능하도록 하는 역할
- 보통 GND에 연결을 해서 항상 LOW로 주고, STCP핀으로만 출력을 제어한다.
7) Reset 핀 : /MR
- 해당 핀이 LOW가 되면 초기화가 되는 핀으로 VCC에 연결하면 아무런 동작을 수행하지 않는다.
※ 해당 핀을 간단하게 사용하기 위해선 3개의 입력핀 11번,12번,14번을 사용하고, 출력으론 8개의 핀 1,2,3,4,5,6,7,15번을 사용하게된다.
1-2. 회로도
- 회로도상에서 SRCLK는 쉬프트 클록(Shift Clock), RCLK는 래치클록(Latch Clock)에 해당 된다.
- DS핀(SER)을 통해 들어온 비트 값이 Shift Register와 Storage Register에 저장이 되는데 SRCLK가 HIGH가 되면 쉬프트 래치스터에서 스토리지 레지스터로 이동을하고 RCLK가 HIGH가 되면 스토리지 레지스터에서 출력핀(QA~QH)으로 해당 비트가 각각 출력이 된다.
※ 위의 회로도를 이해하기 위한 기초 상식!!
- 네모는 각 비트를 저장하는 레지스터에 해당되고, 삼각형은 해당 핀에 들어오는 값을 반전시키는 역할을 한다.
- 삼각형의 위에서 들어오는 값은 해당 값이 HIGH(1)가 되면 데이터 전송을 수행하고, LOW(0)면 데이터를 전송하지 않는다는 뜻이다.
2. 74HC595 칩 동작 과정
(8비트의 데이터 '11001101'의 값이 MSB 우선 전송하는 과정 설명)
※ MSB : Most Significant Bit의 약자로 어떠한 데이터 형의 최상위 비트를 의미
※ LSB : Least Significant Bit의 약자로 어떠한 데이터 형의 최하위 비트를 의미
1) DS핀을 통해 8비트 데이터 전송(MSB 우선)
- 데이터값 '1100 1101'(0xCD)이 DS핀을 통해 전송된다.
- 여기서 주의해야할 점은 MSB 부터 전송되기 때문에 데이터값의 가장 최상위 비트부터 전송한다.
- Latch Clock와 Shift Clock는 'LOW'의 신호를 출력한다.
2) Shift Clock 1회 동작(LOW → HIGH → LOW)
- Shift Clock이 HIGH가 되면 DS핀을통해 전달된 첫번째 비트가 Shift Register와 Storage Register로 이동한다.
3) Shift Clock 2회 동작
- Shift Clock이 2번째로 HIGH가 되면 DS핀을 통해 전달된 두번째 비트가 Shift Register와 Storager Register로 이동한다.
- 첫번째로 이동한 비트는 각 레지스터에서 한 칸 아래로 내려가고 최근에 전달된 비트는 최상단의 레지스터에서 자리잡게 된다.
4) Shift Clock 3회 동작
- Shift Clock이 3번째로 HIGH가 되면 DS핀을 통해 전달된 두번째 비트가 Shift Register와 Storager Register로 이동한다.
- Shift Clock는 HIGH가 된 후 LOW가 되어야 다음 HIGH가 됐을때 비트 이동을 수행할 수 있다.
5) Shift Clock 8회 동작
- Shift Clock이 8번째 HIGH가 되면 DS핀을 통해 전달된 8개의 비트가 MSB 비트부터 각 레지스터에 모두 이동하게 된다.(Shift Register와 Storage Register는 꽉 차게 된다.)
6) Latch Clock 1회 동작(8비트 병렬 출력)
- RCLK에 HIGH 신호가 들어오면 Storage Register에서 저장하고 있는 8개의 비트를 각각 해당하는 핀으로 출력한다.
- MSB부터 전송했기 때문에 최상단의 비트는 레지스터상 최하단에 존재하게 된다.
3. 74HC595 칩 동작 실습
3-1. 실습 사진
- 74HC595N 칩에 8개의 LED를 출력부에 연결해서 8개의 LED를 1개씩 순차적으로 점등하는 동작 수행
3-2. 실습 코드
1) 전처리문
#define F_CPU 16000000L
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
// 'bit' 위치의 비트를 1또는 0으로 설정하기 위한 매크로 함수
#define set_bit(bit) ( PORTB |= _BV(bit))
#define clear_bit(bit) ( PORTB &= ~_BV(bit))
// ATmega128의 포트B에 연결된 위치
#define SHIFT_CLOCK 0
#define LATCH_CLOCK 1
#define DATA 2
- B포트의 0번은 Shift Clock을 위한 핀, 1번은 Latch Clock을 위한 핀, 2번은 직렬 Data 전송을 위한 핀
2) Shift Clock & Latch Clock 함수부
void ShiftClock(void)
{
set_bit(SHIFT_CLOCK); // 이동클록 HIGH
clear_bit(SHIFT_CLOCK); // 이동클록 LOW
}
void LatchClock(void)
{
set_bit(LATCH_CLOCK); // 래치클록 HIGH
clear_bit(LATCH_CLOCK); // 래치클록 LOW
}
- 쉬프트 클록과 래치 클록이 HIGH가 됐을때 비트 이동 및 출력을 수행하기 때문에 HIGH 신호를 보낸 후 LOW로 바꿔준다.
3) 8비트 직렬 데이터 출력 함수부
void ByteDataWrite(uint8_t data) // 1바이트 데이터 출력
{
for(uint8_t i = 0; i<8; i++){
// MSB부터 1비트 출력(최상위비트 : MSB (most significant bit)
if(data & 0b10000000)
set_bit(DATA);
else
clear_bit(DATA);
ShiftClock(); // 1비트 출력 후 비트 이동
data = data << 1; // 다음 출력할 비트를 MSB로 이동
}
LatchClock(); // 1바이트 전달 후 실제 출력 발생
}
- data 인자를 통해 8비트의 데이터값을 받아서 Shift Clock이 HIGH 일때 MSB 비트(최상위 비트)부터 Shift Register 및 Storage Register로 이동한다.
- Latch Clock이 HIGH 가 되면 한번에 8비트를 Storage Register에서 출력 핀을 통해 전송한다.
- if(data & 0b10000000) =
8번째 비트, 즉 MSB부터 비트를 비교해서 if문이 참이면 1을 출력하고 거짓이면 0을 출력한다.
4) Main 함수부
int main(void){
// 제어 및 데이터 핀을 출력으로 설정
DDRB |= _BV(SHIFT_CLOCK) | _BV(LATCH_CLOCK) | _BV(DATA);
uint8_t index = 0; // 켜질 LED 위치
while(1)
{
uint8_t pattern = 1 << index; // 출력 패턴 결정
index = (index + 1) % 8; // 출력 패턴에서의 위치 결정
ByteDataWrite(pattern); // 바이트 데이터 출력
_delay_ms(1000);
}
return 0;
}
- 1비트씩 왼쪽으로 이동하면서(LED 출력 패턴) 1바이트를 출력한다.(1초 간격)
댓글