【51單片機(jī)】點(diǎn)陣LED的顯示實(shí)驗(yàn)
點(diǎn)陣LED顯示實(shí)驗(yàn)
前言
今天女朋友生日,除了禮物之外,一時(shí)想不到能給她點(diǎn)什么不一樣的,并且奈何自己不會(huì)寫(xiě)詩(shī),沒(méi)辦法從這方面入手。所以就用我會(huì)的方式吧。
既然最近自己琢磨琢磨單片機(jī),也準(zhǔn)備玩兒點(diǎn)陣LED的顯示實(shí)驗(yàn),這時(shí)我靈機(jī)一動(dòng),不如用LED做一個(gè)吧。(??????老理工男了,怎么有的女朋友?)
好,下面就來(lái)看看我是怎么做的吧。
一、環(huán)境
環(huán)境用的是Keil5編譯,這是目前比較主流的單片機(jī)編譯軟件,支持匯編和C。其次,我用到了Proteus8軟件仿真,沒(méi)有自己買單片機(jī),仿真軟件的東西很全面。具體的軟件操作在我的上一篇文章中有說(shuō)了,這里就不再贅述。需要看軟件操作的小伙伴可以參考我的這篇文章(點(diǎn)擊閱讀)。
二、硬件
這次用到的原件有80C51、MATRIX-8×8-RED、RESPACK-8,以及POWER和GROUND。
1.了解Matrix-8×8就像你需要了解女朋友
MATRIX-8×8-RED是8×8的紅色LED點(diǎn)陣(除了紅色還有其他顏色,也不止有8×8規(guī)格的),它共有16個(gè)引腳,8個(gè)陽(yáng)極引腳控制列上的LED,8個(gè)陰極引腳控制行上的LED。通常我們把控制行上LED的八位二進(jìn)制數(shù)稱為列值,控制列的二進(jìn)制稱為列選信號(hào)。類似于數(shù)據(jù)與片選信號(hào)的關(guān)系。

上圖就是一個(gè)matrix-8×8的LED,我們無(wú)法從外觀上看出它的陰極和陽(yáng)極,這時(shí)候我們就需要自己找出來(lái)。方法也很簡(jiǎn)單,就是給它加電源。當(dāng)列選端口為高電平,列值為低電平時(shí)LED點(diǎn)亮,利用這一特點(diǎn),很容易找出陰極和陽(yáng)極。如下圖:

我們只需要連接左邊或者右邊一種即可,這里為方便說(shuō)明把兩端都測(cè)試了一遍。打開(kāi)仿真,即可觀察到:

觀察左邊發(fā)現(xiàn):上端輸入高電平的列有LED發(fā)光,說(shuō)明上端是陽(yáng)極(列選),下端是陰極(列值)。而右邊上端低電平下端高電平并沒(méi)有LED亮起,佐證了剛才的結(jié)論。
進(jìn)一步,我們看到陰極輸入01111011,在一列中,從高到低是10000100B。發(fā)現(xiàn)了嗎?陰極低電平時(shí)對(duì)應(yīng)的LED亮起,01111011就是列值。
2、正確地連接線路就像你需要以正確的方式讓她開(kāi)心。
在對(duì)MATRIX8×8有了了解,測(cè)出了端口性質(zhì)。接下來(lái)是連接電路。首先我們需要明確一點(diǎn),80C51的P0口需要上拉電阻才能輸出高電平,具體原因是80C51芯片的設(shè)計(jì)結(jié)構(gòu),在這里就不解釋了(因?yàn)槲乙膊簧趿私猓猾I(xiàn)丑了。有大佬可以評(píng)論區(qū)科普一下嗎?)
這里我們選用P0口做列選,用P2口作列值。于是得到如圖的電路圖:

其中,RESPACK-8是排阻,其八位端口接P0口,作為上拉電阻。Matrix-8×8-RED的陽(yáng)極接P0口(列選),陰極接P2口(列值)。
三、軟件
1、思路就是有一個(gè)給她驚喜的想法
我的設(shè)計(jì)的是先顯示一顆跳動(dòng)的愛(ài)心?,然后把她的名字首字母顯示出來(lái)。根據(jù)這個(gè)想法,我們就很好想到實(shí)現(xiàn)辦法了。
- 首先,我們需要設(shè)置在開(kāi)始的一段時(shí)間內(nèi)讓愛(ài)心跳動(dòng),再讓字母輪流出現(xiàn)。
- 愛(ài)心怎么跳動(dòng)?我們可以用一大一小的愛(ài)心交替顯示表現(xiàn)這種效果。
- 怎么顯示?點(diǎn)陣LED可以用動(dòng)態(tài)掃描法顯示,只需控制好循環(huán)就能顯示圖形。
下面開(kāi)始編寫(xiě)代碼:
2、頭文件就是準(zhǔn)備工作
#include <reg51.h>
int Ledcode[5][8]={ {0x0C,0x1E,0x3E,0x7C,0x7C,0x3E,0x1E,0x0C},//大愛(ài)心
{0x00,0x0C,0x1C,0x38,0x38,0x1C,0x0C,0x00},//小愛(ài)心
{0x32,0x73,0xdb,0xdb,0xdb,0xdb,0xce,0x64},//字母‘S’
{0x01,0x03,0x7f,0xff,0xc3,0xe1,0x60,0x00},//字母‘J’
{0x01,0x03,0x87,0xfc,0xfc,0x86,0x03,0x01}};//字母‘Y’
int line[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//列選
上面的代碼,因?yàn)槲蚁腼@示一顆跳動(dòng)的愛(ài)心,所以在這個(gè)8×8的點(diǎn)陣中設(shè)計(jì)了一個(gè)大愛(ài)心和一個(gè)小愛(ài)心,讓大小愛(ài)心交替顯示,表現(xiàn)出跳動(dòng)的效果。
后面的字母是名字縮寫(xiě)。列選則是每次選擇一列顯示。所有這些都是我一個(gè)一個(gè)畫(huà)出來(lái)再轉(zhuǎn)化的列值。
- 一開(kāi)始是這樣的
![在這里插入圖片描述]()
把它整個(gè)畫(huà)出來(lái)了 - 然后是這樣
![在這里插入圖片描述]()
把列中對(duì)應(yīng)的二進(jìn)制數(shù)寫(xiě)出來(lái),就是列值了。 - 最后,還進(jìn)行了修改,這都是在看到效果后對(duì)一些細(xì)節(jié)修改了。
![在這里插入圖片描述]()
讓大家見(jiàn)笑了。
3、點(diǎn)陣LED顯示就是把想法變成現(xiàn)實(shí)
這里采用的是動(dòng)態(tài)掃描的方式,因?yàn)槊恳涣酗@示的列值都不一樣,所以用動(dòng)態(tài)掃描每次顯示一列,只要循環(huán)的速度足夠快,就能看到一幅靜態(tài)的圖案,這利用的是人眼的視覺(jué)暫留現(xiàn)象。
1)跳動(dòng)愛(ài)心的代碼:
int times=0;
while(times<1500){
P0=line[n];
if(times<=1000) P2=~Ledcode[0][n++];//循環(huán)顯示大愛(ài)心1000次。
else P2=~Ledcode[1][n++];//小愛(ài)心再顯示小愛(ài)心500次.
if(n==8) n=0;//讓列值在數(shù)組中的一行循環(huán)。
times++;
delayms(1);//延時(shí)程序。
}
先循環(huán)顯示大愛(ài)心約1秒,再顯示小愛(ài)心0.5秒,形成一次跳動(dòng)效果。需要跳動(dòng)多次只需要再嵌套一層for循環(huán)即可。:
int times,n=0;
for(i=0;i<3;i++){
times=0;
while(times<1500){
P0=line[n];
if(times<=1000) P2=~Ledcode[0][n++];
else P2=~Ledcode[1][n++];
if(n==8) n=0;
times++;
delayms(1);
}
}
這樣就跳動(dòng)了三次。
然后,當(dāng)愛(ài)心跳動(dòng)了三次,就會(huì)交替顯示字母。利用同樣的方法就能實(shí)現(xiàn)。
2)顯示字母的代碼:
times=0;
n=0;
while(times<=6000){
P0=line[n];
if(times<=2000) P2=~Ledcode[2][n++];
else if(times>2000&×<=4000) P2=~Ledcode[3][n++];
else P2=~Ledcode[4][n++];//三個(gè)字母各顯示2000次,視覺(jué)上顯示了約2秒。
times++;
if(n==8) n=0;
delayms(1);
}
以上是一次的整個(gè)流程,現(xiàn)在需要一直循環(huán)顯示,只需要再嵌套一層大的循環(huán)即可。
如下:
void main(void)
{
int i;
int n=0;
while(1){
int times;
for(i=0;i<3;i++){
times=0;
while(times<1500){
P0=line[n];
if(times<=1000) P2=~Ledcode[0][n++];
else P2=~Ledcode[1][n++];
if(n==8) n=0;
times++;
delayms(1);
}
}
times=0;
n=0;
while(times<=6000){
P0=line[n];
if(times<=2000) P2=~Ledcode[2][n++];
else if(times>2000&×<=4000) P2=~Ledcode[3][n++];
else P2=~Ledcode[4][n++];
times++;
if(n==8) n=0;
delayms(1);
}
}
}
現(xiàn)在主程序完成了,這也只是一個(gè)簡(jiǎn)單的小程序。但是剛才用到了延時(shí)程序,把延時(shí)程序補(bǔ)上就大功告成了。
void delayms(int n){
int i;
int j;
for(i=0;i<n;i++)
for(j=0;j<110;j++);
}
3)附上完整代碼:
int Ledcode[5][8]={ {0x0C,0x1E,0x3E,0x7C,0x7C,0x3E,0x1E,0x0C},//大愛(ài)心的列值
{0x00,0x0C,0x1C,0x38,0x38,0x1C,0x0C,0x00},//小愛(ài)心的列值
{0x32,0x73,0xdb,0xdb,0xdb,0xdb,0xce,0x64},//字母‘S’列值
{0x01,0x03,0x7f,0xff,0xc3,0xe1,0x60,0x00},//字母‘J’列值
{0x01,0x03,0x87,0xfc,0xfc,0x86,0x03,0x01}};//字母‘Y’列值
int line[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//列選
void delayms(int n){
int i;
int j;
for(i=0;i<n;i++)
for(j=0;j<110;j++);
}
void main(void)
{
int i;
int n=0;
while(1){
int times;
for(i=0;i<3;i++){
times=0;
while(times<1500){//顯示跳動(dòng)愛(ài)心
P0=line[n];
if(times<=1000) P2=~Ledcode[0][n++];//顯示大愛(ài)心
else P2=~Ledcode[1][n++];//顯示小愛(ài)心
if(n==8) n=0;
times++;
delayms(1);
}
}
times=0;
n=0;
while(1){//輪流顯示字母
P0=line[n];
if(times<=2000) P2=~Ledcode[2][n++];//顯示字母‘S’
else if(times>2000&×<=4000) P2=~Ledcode[3][n++];//顯示字母‘J’
else P2=~Ledcode[4][n++];//顯示字母‘Y’
times++;
if(n==8) n=0;
delayms(1);
if(times==6000) break;
}
}
}
四、效果——女朋友獲得愛(ài)意,你獲得女朋友

點(diǎn)陣太小,放大了看不清楚,所以縮小了看更能把圖形顯示清楚。
總結(jié)
代碼很簡(jiǎn)單,程序也很簡(jiǎn)單,但是重要的是心意嘛。她還是很喜歡的,當(dāng)然,女生可能對(duì)硬件是沒(méi)多少興趣的,她更注重的是顯示的效果和我為了這個(gè)效果做的努力。
順便,記錄一下第一篇文章閱讀破百,小萌新的激動(dòng)就是這么簡(jiǎn)單。



浙公網(wǎng)安備 33010602011771號(hào)