實(shí)驗準備
課程內容
LED 增加8只
電阻 10k,增加8只
LED點(diǎn)陣 8x8
(或直接使用完整的開(kāi)發(fā)板)
要繼續增加控制LED數量,在P1的8個(gè)IO口用完的情況下,選擇P2接另外8只LED,然后程序稍做修改,直接加入對P2的控制即可。
一般情況下,在啟動(dòng)KEIL軟件之前,從之前的工程中復制一份出來(lái)修改使用,這有兩個(gè)好處,一是保留前面的實(shí)驗成果,二是無(wú)需再花時(shí)間輸入相同的內容,復制后只須修改小小即可,省時(shí)省力。復制與粘貼這兩個(gè)操作一定要熟練掌握。
例如,把之前的工程myled1 整個(gè)文件夾復制一份為myled2,只需在KEIL中打開(kāi)這文件夾中的工程即可省去建新工程與設置的步驟。
以第三課其中一段程序修改來(lái)實(shí)驗。(僅主程序main(0中增加 P2=~P2;)
#include 'reg52.h'
#define uint unsigned int
#define uchar unsigned char
sbit P10= P1^0;
void mDelay(uint Delay)
{
uint i;
for(;Delay>0;Delay--)
for(i=0;i<>
}
void main()
{
P1=~P1;
P2=~P2;
mDelay(1000);
}
同樣,可參照第三課內容對第2排LED做花樣控制,此處可自由實(shí)驗下。
89C52單片機只有P0、P1、 P2、P3、P4四個(gè)IO組,如果超過(guò)32只LED,那么就不好控制了,例如這里的8x8點(diǎn)陣,里面有64只LED。
分析這LED點(diǎn)陣結構,可以見(jiàn)到,每只LED分別由橫向一線(xiàn)與縱向一條控制,當LED對應橫線(xiàn)設置信號 1(即5V電壓),同時(shí)這只LED縱向的線(xiàn)設置信號0(即0V電壓),這只LED就會(huì )發(fā)光。于是只需兩組IO即可控制LED點(diǎn)陣。
先做個(gè)小實(shí)驗,把LED點(diǎn)陣兩排腳分別接P1與,修改前面的程序main()部分內容,如下:
void main()
{
P1=0xFF; //控制橫向線(xiàn)電壓,提供5V電壓
P2=0xAA; //控制縱向線(xiàn)電壓,產(chǎn)生顯示效果
mDelay(1000);
}
編譯,下載,可以見(jiàn)到LED點(diǎn)陣以行間隔方式點(diǎn)亮了(如果沒(méi)有點(diǎn)亮,把P1、P2對調一下)。
再做下小改,如下:
void main()
{
P1=0xFF; //控制橫向線(xiàn)電壓,提供5V電壓
P2=0xDB; //控制縱向線(xiàn)電壓,產(chǎn)生顯示效果
mDelay(1000);
}
編譯,下載,可以見(jiàn)到LED點(diǎn)陣中間的某些點(diǎn)被控制點(diǎn)亮。
那么,如果想顯示自己想要顯示的指定的內容呢,例如顯示數字,中文等,這就要逐行逐點(diǎn)來(lái)計算哪點(diǎn)位置給個(gè)0,哪點(diǎn)位置給個(gè)1,計算量特大了。
不過(guò),單片機開(kāi)發(fā)的前輩早就編起了一段代碼,我們直接復制過(guò)來(lái)即可使用,當然想深層次學(xué)習,可以仔細研究。這里是易學(xué)教程,我們不用深究。
其實(shí),生產(chǎn)或銷(xiāo)售單片機零件模塊的商家一般都會(huì )附送模塊的資料和單片例程,這方便極了,我們只需要學(xué)會(huì )調用即可。例程如下:
#include 'reg52.h'
#define uchar unsigned char
#define uint unsigned int
//以下兩大段數據稱(chēng)為數組
//數組row中有8個(gè)數,控制LED點(diǎn)陣高電平管腳 ,控制LED橫向線(xiàn)電壓
uchar code row[] ={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//二維掃描數組,不同的顯示內容,只需取出對應的一組數,控制LED縱向線(xiàn)
uchar code word[][8]={
{0x00,0x00,0x3e,0x41,0x41,0x41,0x3e,0x00}, //0
{0x00,0x00,0x00,0x00,0x21,0x7f,0x01,0x00}, //1
{0x00,0x00,0x27,0x45,0x45,0x45,0x39,0x00}, //2
{0x00,0x00,0x22,0x49,0x49,0x49,0x36,0x00}, //3
{0x00,0x00,0x0c,0x14,0x24,0x7f,0x04,0x00}, //4
{0x00,0x00,0x72,0x51,0x51,0x51,0x4e,0x00}, //5
{0x00,0x00,0x3e,0x49,0x49,0x49,0x26,0x00}, //6
{0x00,0x00,0x40,0x40,0x40,0x4f,0x70,0x00}, //7
{0x00,0x00,0x36,0x49,0x49,0x49,0x36,0x00}, //8
{0x00,0x00,0x32,0x49,0x49,0x49,0x3e,0x00}, //9
{0x00,0x00,0x7F,0x48,0x48,0x30,0x00,0x00}, //P
{0x00,0x00,0x7F,0x48,0x4C,0x73,0x00,0x00}, //R
{0x00,0x00,0x7F,0x49,0x49,0x49,0x00,0x00}, //E
{0x00,0x00,0x3E,0x41,0x41,0x62,0x00,0x00}, //C
{0x00,0x00,0x7F,0x08,0x08,0x7F,0x00,0x00}, //H
{0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00}, //I
{0x00,0x7F,0x10,0x08,0x04,0x7F,0x00,0x00}, //N
{0x7C,0x48,0x48,0xFF,0x48,0x48,0x7C,0x00} //中
};
void mDelay(uint Delay)
{
uint i;
for(;Delay>0;Delay--)
for(i=0;i<>
}
void display(uchar word_num)
{ //參數 word_num 就是要顯示的排在數組第幾位置的顯示內容
uchar i;
for(i=0;i<>
{
P2 = row[i]; //取出對應的行掃描控制信號
P0=word[word_num][i]; //取出對應的列掃描控制信號,顯示內容
mDelay(1); //延時(shí)1毫秒(1秒=1000毫秒)
P2=0xff;
P0=0xff;
}
}
void main()
{
display(3); // 如此簡(jiǎn)單調用即可
}
從主程序 main()中可以看到,使用方法實(shí)在太簡(jiǎn)單了,就一個(gè)display()函數,只需換下括號中的顯示參數即可。
現在可以實(shí)踐下了,可以試下找LED點(diǎn)陣廠(chǎng)家配套的例程,或者上網(wǎng)搜索同類(lèi)例程,或者直接就復制這一課教程中的代碼,復制到自己的程序中,只要自己明白自己所調的模塊實(shí)現什么效果,那么這個(gè)程序就變成你自己的程序了。
對于其他的模塊也是類(lèi)似,例如以后學(xué)習的模塊:4段數碼管,8路獨立鍵盤(pán),4x4矩陣鍵盤(pán),Lcd1602,12864液晶屏,蜂鳴器模塊,5軸步進(jìn)電機模塊,超聲波模塊,哨聲模塊,光線(xiàn)控制模塊,DS18B02溫度模塊,VS838紅外接收模塊與7x3紅外搖控器,繼電器控制模塊,帶電池的DS1302實(shí)時(shí)時(shí)鐘模塊,支持SPI的各種模塊,如液晶屏模塊,SD卡模塊,攝像頭模塊,MP3模塊,FM收音機模塊, … …
所以,學(xué)習C51單片機應用并不難,關(guān)鍵就是學(xué)會(huì )『拿』過(guò)來(lái)用,即是復制與粘貼相關(guān)代碼。
從前面的程序中看到,程序一大段代碼,其中實(shí)現的功能可以讓人重復使用。另外,從一些模塊廠(chǎng)家提供的例程中,有些例程的部分代碼是放入一個(gè).h 的文件中。而讓主程序部分簡(jiǎn)潔明了。
這個(gè) . h文件稱(chēng)為 『頭文件』,我們把可把常用的功能搬到頭文件件,這頭文件也可以復制給其他程序中,讓其他程序受益。
示例,建立頭文件 function.h 并化優(yōu)程序。
頭文件function.h內容:(注意保存時(shí),要輸入完整文件名function.h)
#include 'reg52.h'
#define uchar unsigned char
#define uint unsigned int
//以下兩大段數據稱(chēng)為數組
//數組row中有8個(gè)數,控制LED點(diǎn)陣高電平管腳 ,控制LED橫向線(xiàn)電壓
uchar code row[] ={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//二維掃描數組,不同的顯示內容,只需取出對應的一組數,控制LED縱向線(xiàn)
uchar code word[][8]={
{0x00,0x00,0x3e,0x41,0x41,0x41,0x3e,0x00}, //0
{0x00,0x00,0x00,0x00,0x21,0x7f,0x01,0x00}, //1
{0x00,0x00,0x27,0x45,0x45,0x45,0x39,0x00}, //2
{0x00,0x00,0x22,0x49,0x49,0x49,0x36,0x00}, //3
{0x00,0x00,0x0c,0x14,0x24,0x7f,0x04,0x00}, //4
{0x00,0x00,0x72,0x51,0x51,0x51,0x4e,0x00}, //5
{0x00,0x00,0x3e,0x49,0x49,0x49,0x26,0x00}, //6
{0x00,0x00,0x40,0x40,0x40,0x4f,0x70,0x00}, //7
{0x00,0x00,0x36,0x49,0x49,0x49,0x36,0x00}, //8
{0x00,0x00,0x32,0x49,0x49,0x49,0x3e,0x00}, //9
{0x00,0x00,0x7F,0x48,0x48,0x30,0x00,0x00}, //P
{0x00,0x00,0x7F,0x48,0x4C,0x73,0x00,0x00}, //R
{0x00,0x00,0x7F,0x49,0x49,0x49,0x00,0x00}, //E
{0x00,0x00,0x3E,0x41,0x41,0x62,0x00,0x00}, //C
{0x00,0x00,0x7F,0x08,0x08,0x7F,0x00,0x00}, //H
{0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00}, //I
{0x00,0x7F,0x10,0x08,0x04,0x7F,0x00,0x00}, //N
{0x7C,0x48,0x48,0xFF,0x48,0x48,0x7C,0x00} //中
};
void mDelay(uint Delay)
{
uint i;
for(;Delay>0;Delay--)
for(i=0;i<>
}
void display(uchar word_num)
{ //參數 word_num 就是要顯示的排在數組第幾位置的顯示內容
uchar i;
for(i=0;i<>
{
P2 = row[i]; //取出對應的行掃描控制信號
P0=word[word_num][i]; //取出對應的列掃描控制信號,顯示內容
mDelay(1); //延時(shí)1毫秒(1秒=1000毫秒)
P2=0xff;
P0=0xff;
}
}
也就是說(shuō)把幾行常用的預定義#define命令,延時(shí)函數,顯示函數,點(diǎn)陣數據全部放入頭文件中,這樣一來(lái),主程序 就簡(jiǎn)單了,如下:
#include “function.h”
void main()
{
display(3); // 如此簡(jiǎn)單調用即可
}
也就是用一個(gè)命令#include 命令,把頭文件 function.h 包括進(jìn)來(lái)了
以后的學(xué)習也基本采用這種程序結構,模塊功能放頭文件function.h中,主程序更專(zhuān)注于自己要實(shí)現的功能。
聯(lián)系客服