首先要了解74HC595這個芯片:74HC595是一個8位串行輸入、平行輸出的位移緩存器:平行輸出為三態輸出。
這個芯片各個引腳的功能及工作原理如下:
Q0--Q7: 八位
並行輸出端,可以直接控制數碼管的8個段。(用於接LED燈)
Q7':
級聯輸出端。將它接下一個595的DS端。(可以實現級聯)
DS:
串行數據輸入端,級聯的話接上一級的Q7'。
74595的控制端說明:
/MR(10腳): 低電平時將移位寄存器的數據清零。通常我將它接Vcc。
SH_CP(11腳):上升沿時數據寄存器的數據移位。Q0->Q1->Q2-->Q3-->...-->Q7;下降沿移位寄存器數據不變。(脈沖寬度:5V時,大於幾十納秒就行了。我通常都選微秒級)
ST_CP(12腳):上升沿時移位寄存器的數據進入數據存儲寄存器,下降沿時存儲寄存器數據不變。通常我將ST_CP置為低電平,當移位結束后,在ST_CP端產生一個正脈沖(5V時,大於幾十納秒就行了。我通常都選微秒級),更新顯示數據。
/OE(13腳): 高電平時禁止輸出(高阻態)。如果單片機的引腳不緊張,用一個引腳控制它,可以方便地產生閃爍和熄滅效果。比通過數據端移位控制要省時省力。(所以實現流水燈時應接入高電平,用於接地)
要看懂該芯片的時序圖。高處為高電平,低處為低電平。便於理解各個引腳的作用。
我所實現流水燈的代碼為:
#include<reg51.h> #include<intrins.h> int i; sbit SRCLK=P3^6;對應於圖中的ST_CP引腳(注:芯片的引腳名稱經常變化,但是功能是不變的) sbit RCLK=P3^5; //對應於MR (這三條語句是他們連在單片機的位置) sbit SER=P3^4; //對應於SH_CP引腳 void Hc595SendByte(unsigned char dat) // 函數名:Hc595SendByte 函數功能:向74HC595發送一個字節的數據。輸入輸出:無 { unsigned char a; SRCLK=0; // 將兩個引腳置於低電平 RCLK=0; for(a=0;a<8;a++) // 發送8位數 { SER=dat>>7; //通過數據的移位實現流水。從最高位開始發送數據。右移七位 dat<<=1; // SRCLK=1; _nop_(); ////延時函數,系統自帶 _nop_(); SRCLK=0; // 發送時序 RCLK=1; _nop_(); _nop_(); RCLK=0; } } void main() { unsigned char ledNum; ledNum=0xfe; // 燈全滅 while(1) { Hc595SendByte(ledNum); ledNum=_crol_(ledNum,1); for(i=30000;i>0;i--); } }
工作原理:
74HC595為串行輸入,8位並行輸出.&0x80 的用途就是將最高位取出來,然后SH_CP來一個上升沿,寫入到串行。DS=(a<<i)&0x80 的用途就是,依次取出 a 的每一位,並輸入到串行。最后,ST_CP 來一個上升沿,數據寫到寄存器。
for(i=0;i<8;i++)
{
DS=(a<<i) & 0x80;
}
a = 0000 0110 ;
當 i = 0 , a << i 就是 00000110 (a<<i) & 0x80 等於 0
當 i = 1 , a << i 就是 00001100 0
當 i = 2 , a << i 就是 00011000 0
當 i = 3 , a << i 就是 00110000 0
當 i = 4 , a << i 就是 01100000 0
當 i = 5 , a << i 就是 11000000 1
當 i = 6 , a << i 就是 10000000 1
當 i = 7 , a << i 就是 00000000 (a<<i) & 0x80 等於 0
就是依次取出了 a = 0000 0110 它的值(該數據取值0x70的時候也可以實現這一功能)
{
DS=(a<<i) & 0x80;
}
a = 0000 0110 ;
當 i = 0 , a << i 就是 00000110 (a<<i) & 0x80 等於 0
當 i = 1 , a << i 就是 00001100 0
當 i = 2 , a << i 就是 00011000 0
當 i = 3 , a << i 就是 00110000 0
當 i = 4 , a << i 就是 01100000 0
當 i = 5 , a << i 就是 11000000 1
當 i = 6 , a << i 就是 10000000 1
當 i = 7 , a << i 就是 00000000 (a<<i) & 0x80 等於 0
就是依次取出了 a = 0000 0110 它的值(該數據取值0x70的時候也可以實現這一功能)
電路連接圖如下:
