51微控制器LED點陣實驗(74HC595)
實驗目的:用8*8的LED點陣顯示一顆愛心。
實驗儀器:普中開發板(非廣告)
實驗背景:出於一些原因,最近在看Arduino,但仍覺得51好玩。遂,一邊看Arduino,一邊整理51。
8*8的LED點陣電路如圖一所示,有兩種方式。微控制器上整合的電路方式為第二種。
其中,行由P0口控制,列由D7~D0(HC595晶片控制,見下方)控制。
首先考慮,如何先點亮一個燈?
eg:讓P0^7的埠為低電平,P0的其他埠為高電平;D7的埠為高電平,則第一行第一列的led被點亮。
同樣的方式也可以,讓其他單獨的led點亮。
接著考慮,如何控制多個led的點亮?
類似與數碼管的動態顯示,利用餘暉來進行動態顯示。
第一步:P0口先選通某一列,D7~D0控制這一列中哪些燈亮。
第二步:動態顯示每一列。
為了減少微控制器引腳的使用,這裡使用了74HC595晶片。(注:圖二中led的方向反了)。
這圖是醜的沒法看了。但為了敘述清楚,目前也只能這樣了。74HC595晶片詳細的內容可以網上找,也可以直接評論區留言。
HC595晶片的功能:序列輸入,並行輸出。
看如何給
1、D0~D7,並行輸出,接LED。
2、16號和8號引腳,分別接Vcc,Gnd。
3、OE,13號引腳,低電平才輸出有效,讓它接地。
4、10號引腳,主復位引腳,低有效。目前不需要復位,直接接VCC就好.
5、14號引腳SER,接在整合板的P3^4,為序列輸入端。
6、11號引腳SRCLK,接在整合板的P3^6;上升沿時,將序列口RCLK的一位,移位輸入。
7、12號引腳RCLK,接在整合板的P3^5;上升沿時,將移入的8位資料,送到儲存暫存器。
上面的只是使用方法,如果還想繼續深究,可以檢視數電當中的串並行輸入輸出。
程式碼:
#include<reg51.h>
#include<intrins.h>
typedef unsigned char uchar;
sbit SER=P3^4;//14號引腳,序列資料輸入
sbit SRCLK=P3^6;//11號引腳,移位暫存器時鐘輸入
sbit RCLK=P3^5;//12號引腳,儲存暫存器時鐘輸入
uchar code lie[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//p0^7~p0^0,微控制器中,p0^7是高位
uchar code hang[]={0x00,0x38,0x3c,0x1e,0x1e,0x3c,0x38,0x00};//D7~D0
void Hc595SendByte(uchar dat)
{
int i; //編譯可能有點老,變數的定義必須放在塊的開頭
SRCLK=0;//初始化
RCLK=0;
for(i=0;i<8;i++)//從高位到低位,依次序列輸入
{
SER=dat>>7;
dat<<=1;
SRCLK=1;//上升沿,將資料序列輸入
_nop_();//一個機器週期
_nop_();
SRCLK=0;
}
RCLK=1;//上升沿,將資料送入儲存暫存器
_nop_();//一個機器週期
_nop_();
RCLK=0;
}
void delay(int i)
{
while(i--);
}
void main(void)
{
int i;
while(1)
{
for(i=0;i<8;i++)
{
P0=lie[i];//選通列
Hc595SendByte(hang[i]);//送入行
delay(100);
//Hc595SendByte(0x00);//消隱
P0=0xff;//消隱
}
}
}
補充:
1、不是隻有整數才分有符號數和無符號數。char,字元型也有,我感覺挺奇怪的,哈哈。 unsigned char
2、我第一次寫這個程式的標頭檔案是#include<reg52.h>,但是總是報錯,提示RCLK重定義。我仔細檢查程式並沒有發現重定義的地方。後來參看例程式,將標頭檔案改成#include<reg51.h>,程式順利通過。看來52的標頭檔案中應該定義過該變數。就像P0一樣。標頭檔案reg51.h與reg52.h的區別
3、按照C語言的標準,變數的定義必須放在塊的開頭。比如我將主函式中的int i放在for之前寫,程式會報錯。
這個標準已近很老了,現在C99標準中,變數定義的位置比較隨意了,只要使用之前定義就好了。(當然單單這麼說不嚴謹,詳細的可以去網上看看)
4、今天win10剛裝的Kail,埠和win7的有些不同。成功解決win10下微控制器開發板驅動識別問題
5、當然還有最後的結果
用手機拍攝,還是能看到餘暉,肉眼的效果還是很好的。
拓展:這裡每次顯示的都是愛心,所以整體是一個靜態愛心的形狀。
當如果動態顯示的分別是I LOVE DOG,想來也是很好看。但是估計得16*16的尺寸。
苟日新,日日新。