BASIC4MCU | 8051/PIC | PIC | 74HC595를 이용한 포트 확장- Proteus, PIC16F877예제 포함[펌]
페이지 정보
작성자 키트 작성일2017-09-12 11:19 조회6,752회 댓글0건본문
74HC595를 사용법
데이터시트 확인은 기본
<핀>
입력은 SI(=SERIN)으로 0 or 1로 입력되는 데이이고 핀은 14번.
쉬프트클럭은 SCK(=SRCLK)로 SI에 의해 입력된 데이터를 Q0 -> Q1 -> ...-> Q7으로 차례로 이동시키며 핀은 11번.
래치클럭은 RCK(=RCLK)로 저장되어 있는 데이터를 Q0...Q7 핀에 출력시키며 핀은 12번.
쉬프트레지스터 클리어는 /SCRL(=SRCLR)로 저장되어 있는 데이터를 지우는 명령으로 LOW 신호시 지우며 핀은 10번.
출력 가능은 /OE(/G)로 LOW시 사용가능하며 핀은13번.
/SCRL은 Vcc에 /OE는 GND에 접속하고 사용하여도 된다...
<동작>
SI에 데이터를 인가 후 SCK에 펄스를 가하면 rising edge 시점에서 SI의 내용이 QA(=Q0)으로 들어온다. 다시 SCK에 펄스를 가하면 Q0의 내용은 Q1으로 이동하고, SI에 있던 비트는 QA으로 들어온다.
SCK펄스를 줄 때마다 SI->Q->Q1->...->Q7까지 이동한다.
여기서 또 SCK을 가하면 Q7의 내용이 Q7'로 이동하여 FIFO와 같은 형태가된다.
그러나, 아직까지는 레지스터의 내용이 Qx 핀에 반영되지는 않습니다.
RCK에 다시 펄스를 가하면 rising edge 시점에서 LATCH를 타고 Q0 ~ Q7까지의 내용이 각 핀에 반영된다.
즉, 실제로 핀에 출력하게 된다. 단, /G(=/OE)이 LOW에 걸려 있을 때에만 출력이 이루어지니다.
HC595는 시리얼 신호를 패러렐로 변환할 때 많이 사용합니다. 핀수가 모자랄 때 쓰면 유용하죠.
한편, /SCLR에 LOW를 주면 Q0 ~ Q7의 내용이 모두 클리어(0) 되어 버립니다.
패러렐 핀이 8개 가지고 모자랄 때는 HC595를 하나 더 붙여 줍니다.
QH'에서 나온 신호를 다음번 SI에 연결하면 16핀 병렬 신호를 만들어 낼 수 있습니다. 595하나를 더 붙이면 24핀 패러렐이 되니다.
<소스>
#define DATA_SI PORTX0 // = SI, #14 pin
#define SHIFT_CLOCK PORTX1 // = CLK, #11 pin
#define LATCH_CLOCK PORTX2 // = RCK, #12 pin
// /SCRL(#10 pin) = Vcc에연결, LOW= 지움
// /OE(/G, #13 pin) = GND에 연결, LOW=output enable
void HC595write(unsigned char udata){
unsigned char i;
DATA_SI=0;
SHIFT_CLOCK=0;
LATCH_CLOCK=0;
//데이터 쉬프트 부분
i=7;
while(i<=7){
DATA_SI = (udata >> i) & 0x01;
SHIFT_CLOCK=1;
SHIFT_CLOCK=0;
i--;
}
LATCH_CLOCK=1;
LATCH_CLOCK=0;
}
아래에 Proteus 상에서 PIC16F877로 테스트 풀 소스가 있다......
////////////////////////// 작동 소스 ////////////////////////////////
#include <16F877A.h>
#device *=16 adc=10
#byte PORTA = 0x05
#byte PORTB = 0x06
#byte PORTC = 0x07
#byte PORTD = 0x08
#byte TRISA = 0x85
#byte TRISB = 0x86
#byte TRISC = 0x87
#byte TRISD = 0x88
#use delay (clock=4000000)
#fuses XT, NOWDT, NOPUT
#zero_ram
#bit D0=PORTD.0
#bit D1=PORTD.1
#bit D2=PORTD.2
#define DATA_SI D0 // = SI, #14 pin
#define SHIFT_CLOCK D1 // = CLK, #11 pin
#define LATCH_CLOCK D2 // = RCK, #12 pin
// /SCRL(#10 pin) = Vcc에연결, LOW= 지움
// /OE(/G, #13 pin) = GND에 연결, LOW=output enable
/*====== 74HC595 function ==============*/
// write data to 74HC595
void HC595write_data(unsigned char udat);
// shift 1-byte
void HC595write(unsigned char udata);
// shift 2-bytes
void HC595write_2byte(unsigned char udatah,unsigned char udatal);
// shift 3-bytes
void HC595write_3byte(unsigned char udatah,unsigned char udatam,unsigned char udatal);
void main(){
unsigned char sh_a=0, sh_b=0, sh_c=0, i;
set_tris_d(0x00);
while(1){
for(i=0;i<8;i++){
sh_c = 1 << i;
HC595write_3byte(sh_a,sh_b,sh_c);
delay_ms(50);
}
sh_c=0;
for(i=0;i<8;i++){
sh_b = 1 << i;
HC595write_3byte(sh_a,sh_b,sh_c);
delay_ms(50);
}
sh_b=0;
for(i=0;i<8;i++){
sh_a = 1 << i;
HC595write_3byte(sh_a,sh_b,sh_c);
delay_ms(50);
}
sh_a=0;
}
}
void HC595write_data(unsigned char udat){
unsigned char i;
//데이터 쉬프트 부분
i=7;
while(i<=7){
DATA_SI = (udat >> i) & 0x01;
SHIFT_CLOCK=1;
SHIFT_CLOCK=0;
i--;
}
}
void HC595write(unsigned char udata){
DATA_SI=0;
SHIFT_CLOCK=0;
LATCH_CLOCK=0;
HC595write_data(udata);
LATCH_CLOCK=1;
LATCH_CLOCK=0;
}
void HC595write_2byte(unsigned char udatah,unsigned char udatal){
DATA_SI=0;
SHIFT_CLOCK=0;
LATCH_CLOCK=0;
HC595write_data(udatah);
HC595write_data(udatal);
LATCH_CLOCK=1;
LATCH_CLOCK=0;
}
void HC595write_3byte(unsigned char udatah,unsigned char udatam,unsigned char udatal){
DATA_SI=0;
SHIFT_CLOCK=0;
LATCH_CLOCK=0;
HC595write_data(udatah);
HC595write_data(udatam);
HC595write_data(udatal);
LATCH_CLOCK=1;
LATCH_CLOCK=0;
}
댓글 0
조회수 6,752등록된 댓글이 없습니다.