|
1. 74HC164 74HC164是比較典型的移位寄存器,該移位寄存器有一個數據輸入端口、一個時鐘信號端口和八個輸出端口。如圖1所示。
當時鐘信號從低電平變為高電平的時候將輸出一個數據到輸出端D0,當時鐘第二次由低電平變為高電平的時候將輸出第二個數據到D0,而第一個數據將轉移到D1端口。依此類推,每一個時鐘周期中都有一個串行數據輸出到D0,而其他的數據則不斷往高位移動直到所有數據傳輸結束。如果不再有時鐘周期輸入,則這些數據將暫存在輸出端。
注意:初學者會誤以為看到移位的過程,由于移位的時間很短,幾微秒的時間人的眼睛是反應不過來的。 如果需要有更多的輸出端口,可以把多個74HC164串聯起來用。串聯的方法如圖2所示。
在上圖的串聯電路中,左邊的鎖存器D7與右邊鎖存器的串行數據輸入端連接,當左邊的鎖存器D0~D7數據全部輸出以后,再輸入一個串行信號,左邊鎖存器D7數據將作為右邊鎖存器的輸入數據并從右邊鎖存器D0端輸出,從而實現了多個字節數據的移位鎖存。這樣利用74HC164就實現了串行數據到并行數據的轉換。
注意到在上面的兩個圖中,無論輸出什么長度的數據,所需要的輸入信號都只有兩個,一個是串行數據輸入,另一個是鎖存器的時鐘信號輸入。如果我們把這兩個輸入端口連接到單片機的兩個輸出端口上,其中單片機的一個端口串行輸出數據,另一個端口輸出時鐘信號以便控制串行數據的鎖存方式,那么我們就只需要兩個單片機端口幾乎實現任意數量的并口輸出。 2. 8051串口方式0的工作原理與時序
圖3 串口方式0的時序 8051串口方式0的時序如圖所示,RXD(P3.0)為數據端,TXD(P3.1)為同步移位脈沖端,每次串行發送、接收8位數據(一幀),低位在先。時鐘為Fosc/12。 (1) 發送 執行任何一條MOV SUBF,#data指令時,啟動內部串行發送允許,SEND置高電平,隨后在TXD同步移位時鐘的作用下,將數據data從RXD端移位輸出。一幀數據發送完畢時,內部發送中斷請求TI有效。要再次發送一幀時,須用軟件清TI。 (2) 接收 在串行口控制寄存器SCON中,REN=1和RI=0時,會啟動一次接收過程。接收時,TXD仍為同步移位時鐘輸出,而串行移位數據仍從RXD移位輸入。當接收完一幀后,內部接收中斷請求RI有效,要再次接收一幀數據時,須用軟件清零。 3. 電路原理 MCS-51單片機串行口方式0為移位寄存器方式,外接4片74LS164作為4位LED顯示器的靜態顯示接口,把8031的RXD作為數據輸出線,TXD作為移位時鐘脈沖。74LS164為TTL單向8位移位寄存器,可實現串行輸入,并行輸出。其中A、B(第1、2腳)為串行數據輸入端,2個引腳按邏輯與運算規律輸入信號,共一個輸入信號時可并接。T(第8腳)為時鐘輸入端,可連接到串行口的TXD端。每一個時鐘信號的上升沿加到T端時,移位寄存器移一位,8個時鐘脈沖過后,8位二進制數全部移入74LS164中。R(第9腳)為復位端,當R=0時,移位寄存器各位復0,只有當R=1時,時鐘脈沖才起作用。Q1…Q8(第3-6和10-13引腳)并行輸出端分別接LED顯示器的hg···a各段對應的引腳上。在給出了8個脈沖后,最先進入74LS164的第一個數據到達了最高位,然后再來一個脈沖會有什么發生呢?再來一個脈沖,第一個脈沖就會從最高位移出,搞清了這一點,下面讓我們來看電路,4片7LS164首尾相串,而時鐘端則接在一起,這樣,當輸入8個脈沖時,從單片機RXD端輸出的數據就進入到了第一片74LS164中了,而當第二個8個脈沖到來后,這個數據就進入了第二片74LS164,而新的數據則進入了第一片74LS164,這樣,當第4個8個脈沖完成后,首次送出的數據被送到了最左面的164中。
圖4 整體原理圖 4.源程序 /************************************************************* 利用中斷方式進行處理 **************************************************************/ #include<reg51.h> #define uchar unsigned char sbit P3_3=P3^3; uchar a=3; char code tab[]={0x99,0xB0,0xA4,0xF9,0xF9,0xA4,0xB0,0x99};//4321與1234的字形碼 void timer(uchar); void int4(void); void main(void) { uchar i,j; SCON=0; EA=1; ES=1; for(;;) { P3_3=1; for(i=0;i<4;i++) { SBUF=tab[a]; j=a; while(j==a); } P3_3=0; timer(100); if(a==255) a=7; } } void int4(void)interrupt 4 { TI=0; a--; } void timer(uchar t) { uchar i; for(i=0;i<t;i--) { TMOD=0x01; TH0=10000/256; TL0=10000%256; TR0=1; while(!TF0); TF0=0; } } /*****************************************************************************/
|