一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

《中學(xué)生C51單片機易學(xué)實戰(zhàn)入門教程》第二課

 岐岐feng 2018-03-26

《中學(xué)生C51單片機易學(xué)實戰(zhàn)入門教程》

第二課 讓LED閃起來

實驗準(zhǔn)備:使用第一課已裝配好的實驗板

課程內(nèi)容

一、分析LED接線原理圖:

《中學(xué)生C51單片機易學(xué)實戰(zhàn)入門教程》第二課

著重左上角的 LED電路部分。《中學(xué)生C51單片機易學(xué)實戰(zhàn)入門教程》第二課

LED正極接電源5V,現(xiàn)程序控制 LED負(fù)極(原理圖中管腳P1^0)為0V,LED兩端正向有電壓差,于是LED導(dǎo)通,發(fā)光。

那如何控制讓 LED燈 不發(fā)光呢?

只要LED兩端沒有電壓差就可以了,現(xiàn)在LED正極通過電阻已接上5V電壓,只要LED負(fù)極也是5V電壓,LED就不會導(dǎo)通,不發(fā)光了。

上一課中,控制LED負(fù)極電壓的代碼是:

P10 = 0;

表示控制管腳 P1^0的電壓為 0V,現(xiàn)在要改成控制管腳 P1^0的電壓為 5V,這塊單片機芯片只認(rèn)識兩個數(shù)字0與1,0代表0V,1代表5V。于是讓LED燈不發(fā)光,只須改成以下程序代碼:

P10 = 1;

相當(dāng)簡單。

動手改程序,編譯,下載到實驗板中觀察運行結(jié)果。

實驗板沒反應(yīng)?不會壞了吧。

當(dāng)然不是壞,分析下電路原理吧。

在沒有加電的時候,LED燈兩端電壓為0,沒電的狀態(tài)下肯定不會發(fā)光。

當(dāng)下載程序后,實驗板加上電了,LED正極接上了5V電壓,LED負(fù)極讓程序控制了,也是5V電壓,兩端沒有產(chǎn)生能讓LED導(dǎo)通的電壓差,于是LED不發(fā)光。

修改控制LED的代碼改為 P10 = 0; 下載實驗板,LED燈又發(fā)光了。

再修改控制LED的代碼改為 P10 = 1; 下載實驗板,LED燈又不發(fā)光了。

再修改控制LED的代碼改為 P10 = 0; 下載實驗板,LED燈又發(fā)光了。

… …

我想讓LED 像星星一樣閃啊閃,而這樣的只能是不發(fā)光或只發(fā)光的狀態(tài)不合要求。

二、如何才能實現(xiàn)閃的效果?

那就是 先控制LED 發(fā)光一段時間,然后再控制LED不發(fā)光一段時間,如此重復(fù)下去。

單片機的工作狀態(tài)是:只要給它加電,它就永不停息的工作,不斷執(zhí)行設(shè)定的程序,直到斷電或燒壞。

所以,單片機是不會自己暫停一小段時間來讓LED轉(zhuǎn)狀態(tài)的,必須由程序來控制。那單片機既然是永不停息的工作,又如何讓編程序控制單片機暫停一小段時間呢?方法很簡單,就是讓它空跑,做無用的工作,達(dá)到消耗時間的目的,也就是浪費一下它的時間,實現(xiàn)延時效果。

開發(fā)單片機的前輩已設(shè)計好這個消耗時間的程序,稱為延時函數(shù),如下:

void mDelay(uint Delay)

{

uint i;

for(;Delay>0;Delay--)

{

for(i=0;i<>

{

;

}

}

}

先不管這代碼是如何設(shè)計,先把這段代碼輸入到上一課的程序中,并控制LED燈的狀態(tài)切換。

#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()

{

P10=0;

mDelay(1000);

P10=1;

mDelay(1000);

}

要注意,輸入延時函數(shù)時,兩行#define和整個延時函數(shù)代碼要放在主程序段 void main()之前。因為要前面先有代碼功能,后面才可能拿來使用,也就是調(diào)用延時功能。

代碼量增加了,要注意按花括號分層級縮進代碼,方便以后分析程序。

代碼量增加了,這時可能編譯時又會報錯,必須要花時間去排除錯誤,這就叫查BUG和修復(fù)BUG。編代碼,查BUG,修復(fù)BUG,測試,這幾步重重復(fù)復(fù),就是編程序的工作過程。

編譯正確,下載到實驗板上,可以看到達(dá)到了讓LED閃的效果,可是閃得很慢,一秒才閃一下。

想改快點,也很簡單,代碼中的

mDelay(1000);

括號中的數(shù)據(jù)稱為參數(shù),給不同的數(shù)據(jù),延時函數(shù)就有不同的工作效果??梢苑謩e把1000改成500、100、20等做實驗檢驗下效果,實踐是檢驗真理的唯一方法,必須動手做實驗。

三、程序分析

雖然實驗有了效果,但是我們卻仍然不知道為何能有這正確的結(jié)果。

我們來分塊分析。

首先,主程序 main()里面的代碼,容易理解,只要知道代碼

mDelay(1000);

能延時一秒就行了。

然后再看mDelay 延時函數(shù)內(nèi)部代碼及相關(guān)代碼,這回多了兩行代碼,這兩行稱為預(yù)編譯定義:

#define uint unsigned int //用 uint 代表unsigned int

#define uchar unsigned char //用uchar 代碼unsigned char

以后的程序中所有的uint 和uchar 在代碼編譯時會自動換成unsigned int和unsigned char,也就是就輸入代碼量減少了,但結(jié)效果不變,省時省力。

這兩行基本代碼以后的程序中都會出現(xiàn)。

void mDelay(uint Delay) //功能模塊:延時函數(shù),帶控制參數(shù)

{

uint i; //后面要用到的臨時變量,使用前要先定義

for(;Delay>0;Delay--) //不斷重復(fù)運行括號的代碼,直到Delay減到0

{

for(i=0;i<124;i++)>

//直到i加到124才停止

{

; // 僅分號,沒命令,效果是運行一次就空轉(zhuǎn)一次

}

}

}

要點:其中 for()這行括號里面,第一位置放的是初始值,留空的話表示不用管初始值,中間位置放置控制結(jié)束的條件,條件符合就繼續(xù)工作,條件不符合時就退出,第三位置放置的是每完成一次工作后要做的小小改變,達(dá)到控制程序的目的。

這個for()命令,稱為循環(huán)結(jié)構(gòu),用于重復(fù)做一段相同的工作。

四、程序優(yōu)化

優(yōu)化程序,能讓編程素質(zhì)提高。

細(xì)心的同學(xué)可能會發(fā)現(xiàn),在main()程序段中

P10=0;

mDelay(1000);

P10=1;

mDelay(1000);

先控制了LED發(fā)光,然后延時1秒,再控制LED不發(fā)光,然后延時1秒,然后 … … 沒有然后了,程序結(jié)束了。但是為何程序卻能按原意重復(fù)一閃一閃?

沒錯,程序的確是結(jié)束了。

于是LED不發(fā)光了。

但是,由于單片機加電之后是永不停息的工作,于是它重新回到初始加電狀態(tài),于是又從頭再次執(zhí)行了 main()代碼,于是LED又閃了。

也就是說,這個LED不停閃動。并不是我們的程序控制,而是單片機需要不停工作。

這可不行,這方式中有部分時間不是由程序控制,也就是不可控。這是編程大忌,絕不能讓程序編著編著變成不由我控制了。

那個不停的工作也必須由代碼控制。

剛好,剛學(xué)會使用的 for()循環(huán)結(jié)構(gòu)派上用場了。

給LED燈加上永遠(yuǎn)循環(huán)的控制,main()主程序變成:

void main()

{

for(;;)

{

P10=0;

mDelay(1000);

P10=1;

mDelay(1000);

}

}

也就是不用管初始條件,不用管是否結(jié)束,只要做下去就是了。

繼續(xù)優(yōu)化。

功能增加了,代碼也增加了,單片機做的工作也多了,這樣工作時間就花多了,于是工作效率就下降了。

為提高效率,程序可以修改成如下:

#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()

{

P10=!P10;

mDelay(1000);

}

可以看到,程序長度一下子少了一半,這是因為 C語言中,如果控制的命令只有一行,那么可以省去配對的花括號。

主程序main()中,命令由原來的4行變成2行,只因一個嘆號!

符號!是C語言的一個運算符,就像數(shù)學(xué)課中的 +(加) –(減)一樣,它的作用是取反,單片機只認(rèn)識0與1兩個數(shù),0取反就是1,1取反就是0 。

P10=!P10;

這代碼就實現(xiàn)了每次循環(huán)讓P10在0與1之間改變,達(dá)到控制閃的目的。

五、增補C語言注釋功能

為增加程序可讀性,可以在代碼行后面使用//符號,并加入文字說明,幫助理解這段代碼的功能,還可以使用 /* 說明文字 */ 方式注釋,其中說明文字部分可以分多行。

附記:

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    免费黄片视频美女一区| 欧美国产日本高清在线| 国产精品国三级国产专不卡| 亚洲综合激情另类专区老铁性| 国产综合一区二区三区av| 国产精品福利精品福利| 东京热一二三区在线免| 麻豆剧果冻传媒一二三区| 男人和女人草逼免费视频| 精品久久综合日本欧美| 日本二区三区在线播放| 天堂热东京热男人天堂| 沐浴偷拍一区二区视频| 六月丁香六月综合缴情| 欧美日韩国产一级91| 欧美不卡午夜中文字幕| 欧美一区二区三区播放| 亚洲中文字幕在线综合视频| 一区二区日韩欧美精品| 国产日韩综合一区在线观看| 亚洲在线观看福利视频| 色欧美一区二区三区在线| 肥白女人日韩中文视频| 国产自拍欧美日韩在线观看| 日韩一级免费中文字幕视频| 日韩欧美一区二区久久婷婷 | 亚洲午夜福利不卡片在线| 日韩欧美国产三级在线观看| 色欧美一区二区三区在线| 不卡一区二区在线视频| 亚洲超碰成人天堂涩涩| 内射精子视频欧美一区二区| 大香蕉伊人精品在线观看| 一区二区三区亚洲天堂| 欧美在线视频一区观看| 久久国产精品熟女一区二区三区| 国产亚洲成av人在线观看| 神马午夜福利免费视频| 精品高清美女精品国产区| 国产一级精品色特级色国产| 欧美日韩三区在线观看|