74HC595: 8-bit serial-in, serial or parallel-out shift register with output latches; 3-state
이 595를 아두이노의 gpio와 인터페이스하는 코드는,
// // 8 LEDs control // // each LED is connected to 74HC595's output // // Pin connected to ST_CP of 74HC595 int latchPin = 12; // Pin connected to SH_CP of 74HC595 int clockPin = 13; // Pin connected to DS of 74HC595 int dataPin = 11; void LED_out(uint8_t value) { digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, value); digitalWrite(latchPin, HIGH); } void setup() { // set pins to output so you can control the shift register pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { unsigned char value = 0x80; while (1) { for (value = 0x01; value < 0x80; value <<= 1) { LED_out(value); delay(500); } for (value = 0x80; value != 0x00; value >>= 1) { LED_out(value); delay(500); } LED_out(0xff); delay(1000); LED_out(0x00); delay(1000); LED_out(0xff); delay(1000); LED_out(0x00); delay(1000); } }
코드를 보면 연결은 쉽게 추측할 수 있다.
Q0 ~ Q7까지가 출력으로 LED의 anode에 직접 연결했다.
이때의 출력 파형은,
595의 SHCP (clock)과 DS (data)
SHCP와 STCP
ATmega128의 SPI와 74HC595의 연결
atmega128의 신호는
PB0 (pin#10) 는 nSS로, GPIO로 제어. SPI 슬레이브로 128을 설정할 때는 자동으로 PB0는 SPI의 nSS, input으로 셋팅되지만, master일 때는 따로 구동을 해줘야 한다. chip select라 생각하면 된다. 595의 STCP(#12)와 연결한다.
PB1 (pin#11) 은 SCK로, master 설정시 SPI SCK output으로, slave 설정시 SCK input으로 셋팅된다. 595의 SHCP (#11)와 연결한다.
PB2 (pin#12) 는 MOSI 로, master 설정시 output으로, slave 설정시 input으로 셋팅된다. 595의 DS(#14)에 연결한다.
595의 nOE 은 GND에, nMR은 Vcc에 연결한다. Q0 ~ Q7은 출력.
595는 SHCP (SCK) 의 rising edge에서 data (MOSI, DS)가 샘플되므로 (shift), 128의 레지스터 SPCR 의 CPOL 과 CPHA 를 '0' (default) 로 설정한다.
/* * spi_74595.c * * Created: 2014-04-21 오후 9:11:36 * Author: Don Quixote */ #define F_CPU 16000000UL #include <avr/io.h> #include <util/delay.h> #define DD_SS 0 // PB0 #define DD_SCK 1 // PB1, output when SPI master #define DD_MOSI 2 // PB2, output when SPI master void SPI_MasterInit(void) { /* Set MOSI and SCK output, all others input */ DDRB = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS); /* set nSS to high (normal) */ PORTB |= 0x1; /* set SPI2X: Double SPI Speed Bit */ SPSR |= 0x01; /* Enable SPI, Master, set clock rate fck/16 */ SPCR = (1<<SPE)|(1<<MSTR); // fosc / 2 // SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0); // fosc / 64 } void SPI_MasterTransmit(uint8_t cData) { /* set nSS to low (select SPI slave) */ PORTB &= 0xfe; /* Start transmission */ SPDR = cData; /* Wait for transmission complete */ while(!(SPSR & (1<<SPIF))) ; /* set nSS to high */ PORTB |= 0x01; } int main(void) { uint8_t ch; SPI_MasterInit(); while(1) { for(ch = 0x01; ch != 0; ch <<= 1) { SPI_MasterTransmit(ch); _delay_ms(50); } for(ch = 0x80; ch != 0; ch >>= 1) { SPI_MasterTransmit(ch); _delay_ms(50); } } }
출력파형.
SCK를 fosc / 64 로 설정했을 때.
fosc / 2 로 설정했을 때.