當(dāng)我們在搭建arduino項目時,時常因為需要接入按鈕、傳感器、舵機、LED等而遇到I/O口不足的問題,此時就需要使用到74HC595。
74HC595是一個8位串行輸入、并行輸出(SIPO,Serial-In-Parallel-Out)的移位寄存器。其具有8個輸出引腳,而只需要3個輸入引腳。并可以串接多個IC實現(xiàn)更多輸出引腳需求。
引腳圖
74HC595引腳圖
GND | 連接到Arduino的GND |
VCC | 連接到Arduino的5V |
SER | 串行輸入,用于向移位寄存器存入數(shù)據(jù),一次一位(bit) |
SRCLK | 移位寄存器時鐘,74HC595由上升沿驅(qū)動,當(dāng)向移位寄存器寫入數(shù)據(jù)時,SRCLK必須為高電平。 |
RCLK(latch) | 鎖存器時鐘,高電平時,移位寄存器的內(nèi)容拷貝到鎖存寄存器,同時表現(xiàn)為輸出。Latch相當(dāng)于一個閥門。 |
SRCLR | 低電平有效??梢砸淮涡詫⒁莆患拇嫫魉?span id="jimxzbz" class="wpcom_tag_link">位置為0。通常情況此引腳連接高電平。 |
OE | 低電平有效。高電平時輸出引腳禁用或為高阻態(tài)。低電平時輸出引腳正常工作。 |
QA-QH | 輸出引腳,可以連接LED或者7段數(shù)碼管 |
QH‘ | 可用于串接74HC595。當(dāng)此引腳連接到SER引腳,并同時給2個IC同樣的時鐘,則可認(rèn)為是一個具有16個輸出的IC。在保證電源供應(yīng)的情況下,可以串接多個IC。 |
工作原理
74HC595具有2個寄存器(可理解為2個存儲容器),每個可以存儲8位(bit)數(shù)據(jù)。
- 一個叫做移位寄存器,用于接收輸入數(shù)據(jù)。
- 當(dāng)74HC595接收到時鐘脈沖時:
- 移位寄存器中的位置向左移動一位。
- 移位寄存器的Bit0(右邊第一位)接收當(dāng)前DATA引腳的數(shù)據(jù),如果脈沖上升沿時data引腳為高電平則為1并寫入移位寄存器,反之則為0。
- 當(dāng)使能(高電平)RCLK(latch)引腳時,移位寄存器中的數(shù)據(jù)會拷貝到第二個寄存器,存儲(鎖存)寄存器。其每個位(bit)均對應(yīng)連接到QA-QH輸出引腳,因此當(dāng)存儲(鎖存)寄存器中內(nèi)容發(fā)生變化時,相應(yīng)的表現(xiàn)在輸出引腳上。
移位寄存器和鎖存寄存器原理圖
實驗1:使用Arduino和74HC595控制LED
實驗材料
- 5mm LED *8
- 220歐電阻 *8
- 74HC595芯片 *1
- 面包板 *1
- Arduino Uno R3 *1
- 杜邦線 若干
面包板視圖
Arduino代碼
int latchPin = 5; //RCLK int clockPin = 6; // SRCLK int dataPin = 4; // SER byte leds = 0; void setup() { // put your setup code here, to run once: pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { // put your main code here, to run repeatedly: leds = 0; // all leds off updateShiftReg(); delay(500); for(int i=0; i<8; i++){ bitSet(leds, i); updateShiftReg(); delay(500); } } void updateShiftReg(){ digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); } |
代碼解析
byte leds = 0; |
byte數(shù)據(jù)類型為8位(bit),剛好能對應(yīng)8個輸出以及8個led。
bitSet(leds, i); |
bitSet(x, n):設(shè)置變量的某一位(位置為1)。
- X:要設(shè)置位的變量
- n:要設(shè)置變量的哪一位,從最右邊0開始為最低有效位。
updateShiftReg(); |
updateShiftReg()函數(shù)首先將latch鎖存引腳置為低電平,然后調(diào)用shiftOut()移位函數(shù),然后再將latch鎖存引腳置為高電平實現(xiàn)輸出。
shiftOut(dataPin, clockPin, LSBFIRST, leds); |
shiftOut(dataPin, clockPin, bitOrder, value)函數(shù)可以實現(xiàn)每次調(diào)用時對寄存器進行移位操作。
- 參數(shù)1和2位數(shù)據(jù)和時鐘。
- 參數(shù)3指定從數(shù)據(jù)的那一端開始,如果從最右邊的位開始向左移,則稱為“Least Significant Bit First”(LSBFIRST)。反之則從左邊的位開始向右移,則稱為Most Significant Bit First”(MSBFIRST)。
- 參數(shù)4為實際需要進入移位寄存器的數(shù)據(jù)。允許的數(shù)據(jù)類型:byte。
實驗二:使用PWM控制LED的亮度
原理:
通過控制IC的OE引腳來控制LED的亮度。OE(Output Enable)引腳位低電平有效,高電平時位禁止輸出,低電平時為正常輸出。當(dāng)通過analogWrite() 函數(shù)使用PWM控制,則可以實現(xiàn)LED的亮度調(diào)節(jié)。
實際再PWM的高電平時,OE引腳會短暫的金庸IC輸出,但此過程高于人眼所能感知的頻率,因此能實現(xiàn)亮度明暗的變化。
面包板視圖
Arduino代碼
int latchPin = 5; //RCLK int clockPin = 6; // SRCLK int dataPin = 4; // SER int oePin = 3; // OE Ctrl PWM byte leds = 0; void setup() { // put your setup code here, to run once: pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(oePin, OUTPUT); } void loop() { // put your main code here, to run repeatedly: setBright(255); leds = 0; // all leds off updateShiftReg(); delay(500); for(int i=0; i<8; i++){ bitSet(leds, i); updateShiftReg(); delay(500); } for(byte br=255; br>0; br–){ setBright(br); delay(50); } } void updateShiftReg(){ digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); } void setBright(byte br){ analogWrite(oePin, 255-br); } |
實踐:注意確認(rèn)引腳連接無誤后再接通電源
視頻:文章修改時無法添加視頻