隋杰峰
流水燈項目是我們在開源硬件學習項目中很常見的一個項目。實驗中,我們常用一個管腳控制一個LED,這樣我們做一個8位流水燈,就需要占用8個管腳,而常用的Arduino UNO R3開發(fā)板只有20個管腳,如果要做一個30位流水燈,如果依然讓一個管腳控制一個LED,那么UNO上的管腳顯然是不夠的,這時,我們應該怎么辦呢?換成管腳更多的Mega2560嗎?同樣,如果我們要做64位流水燈,Mega2560的管腳也是不夠的,所以,我們換個角度來想,不如想辦法用少量的管腳控制多個LED,74HC595移位寄存器這個小小的芯片就能夠幫我們實現(xiàn)這種想法。
74HC595是一塊8位串行輸入、并行輸出(也可以串行輸出)的芯片,我們使用它,只需要UNO的3個管腳即可控制8個獨立的LED(如圖1)。
網(wǎng)絡(luò)上介紹74HC595的文章很多,但采用的全是代碼編程,讓很多不懂代碼的初學者望而生畏,實際上,在圖形化編程軟件Mixly中有一個模塊是與它相關(guān)的。因此,本文中將用Mixly輕松玩轉(zhuǎn)74HC595,力圖讓初學者也能秒懂。
如圖2所示,74HC595共有16只腳,下面我們就來認識一下它的各個引腳。
在74HC595芯片上有個小凹口,只要與圖上引腳的小凹口對應,即可知道它的各個引腳。
VCC和GND自不必說,分別接UNO的5V和GND即可;
Q0~Q7是并行輸出,本文中我們接8個LED;
DS、SHCP(下面簡稱SH)、STCP(下面簡稱ST)是輸入端;
DS是串行數(shù)據(jù)輸入端(一般Arduino的代碼里會定義一下引腳,74HC595的案例中,dataPin指的是接這個腳);
SH是串行時鐘輸入端(clockPin指的是接這個腳);
ST是鎖存端(latchPin指的是接這個腳);
OE是輸出使能引腳,低電平時輸出,高電平時不輸出,所以,直接接在GND上使其一直保持低電平輸出數(shù)據(jù);
MR是用來重置內(nèi)部寄存器的引腳,低電平時重置內(nèi)部寄存器,所以,直接連接在VCC上一直保持高電平;
Q7S是串行輸出(可以接下一個74HC595的DS,數(shù)據(jù)可作為串行輸入,這就是74HC595的級聯(lián),也就是說,此時3個輸入控制16個輸出),此引腳不用可以空置。
需要的元件(如下頁表所示)
電路連接
電路連接如下頁圖3所示,8個LED的負極(短腳)分別通過一個220Ω電阻與GND連接;74HC595有小凹口的一面向左,VCC接5V,VCC與GND之間接一個104電容,GND接GND;DS接管腳2,ST接管腳3,SH接管腳4,OE接GND,MR接VCC,Q7S空置。
程序設(shè)計
應用74HC595做流水燈,在Arduino IDE中我們會用到shiftOut這個函數(shù),在Mixly中也有對應的模塊,如圖4所示。
首先,我們通過一個程序來了解一下74HC595串行輸入、并行輸出的過程。將圖5程序上傳,我們會發(fā)現(xiàn)Q7腳接的燈是亮的,如圖6所示。
下面,我們來解釋一下這個過程:
首先,管腳3給了鎖存端(ST)一個低電平,意思是說“嗨,74HC595,開始干活了”,然后,管腳2給了數(shù)據(jù)(DS)一個十進制數(shù)1,關(guān)鍵是74HC595不認識它,所以,就需要轉(zhuǎn)換成8位的二進制數(shù)00000001,不足8位的,前面加0補足8位,為啥是8位的?因為,74HC595是8位移位寄存器,有8個輸出(如圖7)。
這時候,時鐘(SH)開始干活了,管腳4每制造一次上升沿(先拉低電平再拉高電平),這一串數(shù)就進去一個,8次之后,都進去了,每個數(shù)就都有自己的一個位置了,即每個動作只操作一位數(shù)據(jù),這就叫串行輸入(如圖8)。
至于誰先進去,進去之后,每一個數(shù)字都在哪個位置,這得看是低位先入還是高位先入,什么意思呢?我們先要弄明白低位和高位,以二進制數(shù)00000001為例,左邊0這一端是高位,右邊1這一端是低位,所以,低位先入的意思就是從最右邊的1(低位)開始依次進入,直到最左邊的0(高位)進去;高位先入的則剛好相反,從最左邊的0(高位)開始依次進入,直到最右邊的1(低位)進去。
下面我們以低位先入為例,用上大巴車做個比方:在二進制數(shù)00000001中,低位先入,給SH腳制造一次上升沿(我們可以理解為檢票),那第一個上大巴車的肯定是最右邊的1,它上去了之后,就占據(jù)了第一排的位置(如圖9)。
繼續(xù)給SH腳制造一次上升沿之后,1左邊的0,開始上車,然后,它并不是走向第二排座位,而是讓1往后挪一個,它坐第一排(如圖10)。
繼續(xù)給SH腳制造一次上升沿,已經(jīng)上車的1和0繼續(xù)往后挪,新上車的0占據(jù)第一排座位(如圖11)。
如此繼續(xù)給SH腳制造上升沿,高位的0,繼續(xù)上車,車上的數(shù)繼續(xù)往后排順延,直到發(fā)生第8次上升沿,所有的數(shù)字都上車了(如圖12)。
然后,管腳3給了鎖存端(ST)一個高電平,讓每個數(shù)都記住自己的位置,在自己的位置坐著(絕對不允許換座位)(如圖13)。
最后,每個數(shù)掌管一個輸出,即每個動作操作多位(這里是8位)數(shù)據(jù),這就是并行輸出。這樣,Q0~Q6腳都得到了一個0(低電平),Q7腳得到一個1(高電平),所以,Q0~Q6腳接的燈都是滅的,Q7腳接的燈是亮的。
同樣的道理,將數(shù)據(jù)輸入改為3,程序如圖14所示。這時候,我們把十進制數(shù)2變?yōu)?位二進制就是00000011,采用低位先入,按照我們上面的推算方法,應該是Q6、Q7高電平,其余低電平,Q6腳和Q7腳接的LED亮,實驗結(jié)果也是如此(如圖15)。
下面,我們再看高位先入,輸入數(shù)據(jù)1,將程序繼續(xù)改動(如圖16),我們會發(fā)現(xiàn),結(jié)果正好與程序1低位先入相反。這是因為,將十進制1轉(zhuǎn)換為8位二進制為00000001,高位先入,即從左邊的0依次進入移位寄存器。最終,Q0對應的是1,高電平,其他腳對應的是0,低電平,所以,Q0接的LED亮,其他腳接的LED滅(如圖17)。
同樣,我們也可以繼續(xù)改變輸入的數(shù)值,設(shè)置低位先入或高位先入,控制這8個LED的亮滅,不過,我們輸入的數(shù)值盡量不要超過255。當我們輸入255,上傳程序后,燈是全部都亮的,我們把十進制的255轉(zhuǎn)換為二進制為11111111,這已經(jīng)是8位二進制最大的數(shù)了,所以,0到255這總共256個數(shù)值就已經(jīng)能全部體現(xiàn)出8個LED亮滅的所有情形。