通過(guò)前幾章,我們組建了我們自己的小單片系統(tǒng),學(xué)會(huì)了編程燒寫(xiě)的方法,那么如何用它去控制LED呢,緣緣先帶你去串串門(mén),認(rèn)識(shí)認(rèn)識(shí)那此單片內(nèi)的小空間吧: 一、了解單片內(nèi)部結(jié)構(gòu),為后面編程控制打基礎(chǔ): 咱們其它的先不要看,會(huì)在以后用到的時(shí)候進(jìn)行講解說(shuō)明,就瞧瞧這四個(gè)與外界相連的這部分空間吧: 51單片機(jī)在設(shè)計(jì)時(shí)有四個(gè)并行I/O口,每個(gè)端口都有8位準(zhǔn)雙向口,共占有32條引腳,每一條I/O線都能獨(dú)立地用途輸入或輸出,每個(gè)端口都包括一個(gè)數(shù)據(jù)鎖存器(即特殊功能寄存器P0-P3)。 鎖存器是干什么的呢,廣義上講,就是可以定義數(shù)值,并寫(xiě)入數(shù)值的一種存儲(chǔ)器,打個(gè)比方,就是咱們的U盤(pán),我們往里面復(fù)制一首歌,這個(gè)歌就會(huì)一直存在,相當(dāng)于被鎖存了,當(dāng)我們不要這首歌時(shí),我們就會(huì)刪除它,從某種意義上講,這時(shí),鎖存器也改變了狀態(tài)。 那么每個(gè)鎖存器是怎么回事呢,如下圖: 對(duì)于這個(gè)鎖存器,從原理上很難說(shuō)明白,什么地上拉電阻、場(chǎng)效應(yīng)、與非門(mén)啦,搞上半天都弄暈了,不過(guò)我們可以這樣理解,把它們看做是一組開(kāi)關(guān),每個(gè)里面都有8個(gè),每個(gè)開(kāi)關(guān)都接一根線。 那么怎么去控制他們呢,這里,我們記住一個(gè)概念,即在數(shù)字電路中,高電平是1,低電平是0,假設(shè)我們上面一個(gè)開(kāi)關(guān)是這樣的,也就是在沒(méi)有定義的時(shí)候,它們是斷開(kāi)的: 當(dāng)我們定義成1時(shí),它接高電平,即與電源VCC相連: 當(dāng)我們定義成0時(shí),它接低電平,即與電源GND相連: 還記得上一章那個(gè)LED是怎么點(diǎn)亮的嗎: 就是當(dāng)電源與負(fù)極接通時(shí),我們的LED就亮了,通過(guò)上面的講解,我們明白了定義與它們電位對(duì)應(yīng)關(guān)系,所以我們對(duì)LED控制時(shí),只要定義成0與1就OK了,如果我們定義開(kāi)關(guān)為1時(shí),這時(shí)與高電平接通VCC,那么,我們的LED兩邊都是高電平,肯定點(diǎn)不亮了: 如果我們定義開(kāi)關(guān)為0時(shí),這時(shí)與低電平GND接通,這時(shí)電路處于通路狀態(tài),LED就被點(diǎn)亮了。 那么如何去控制這個(gè)開(kāi)關(guān)呢,答案是用程序控制,就是我們常聽(tīng)說(shuō)的瑪雅文字——C語(yǔ)言,在開(kāi)始程序前,我們有一點(diǎn)點(diǎn)小知識(shí)了解下,那就是上節(jié)說(shuō)的,為了什么要接8個(gè)電阻,而且這8個(gè)電阻接在了P0口,這8個(gè)電阻有什么用,阻值有什么限定,那么,親們,認(rèn)真看看吧: 關(guān)于P0口接上拉電阻的解釋:(可要記下哦) P0口作為I/O口輸出的時(shí)候時(shí),輸出低電平為0輸出高電平為高組態(tài)(并非5V,相當(dāng)于懸空狀態(tài),也就是說(shuō)P0口不能真正的輸出高電平)。給所接的負(fù)載提供電流,因此必須接上拉電阻(一電阻連接到VCC),由電源通過(guò)這個(gè)上拉電阻給負(fù)載提供電流。P0作輸入時(shí)不需要上拉電阻,但要先置1。因?yàn)镻0口作一般I/O口時(shí)上拉場(chǎng)效應(yīng)管一直截止,所以如果不置1,下拉場(chǎng)效應(yīng)管會(huì)導(dǎo)通,永遠(yuǎn)只能讀到0。因此在輸入前置1,使下拉場(chǎng)效應(yīng)管截止,端口會(huì)處于高阻浮空狀態(tài),才可以正確讀入數(shù)據(jù)。 由于P0口內(nèi)部沒(méi)有上拉電阻,是開(kāi)漏的,不管它的驅(qū)動(dòng)能力多大,相當(dāng)于它是沒(méi)有電源的,需要外部的電路提供,絕大多數(shù)情況下P0口是必需加上拉電阻的。 1.一般51單片機(jī)的P0口在作為地址/數(shù)據(jù)復(fù)用時(shí)不接上拉電阻。 2.作為一般的I/O口時(shí)用時(shí),由于內(nèi)部沒(méi)有上拉電阻,故要接上上拉電阻!! 3.當(dāng)p0口用來(lái)驅(qū)動(dòng)PNP管子的時(shí)候,就不需要上拉電阻,因?yàn)榇藭r(shí)的低電平有效; 4.當(dāng)P0口用來(lái)驅(qū)動(dòng)NPN管子的時(shí)候,就需要上拉電阻的,因?yàn)榇藭r(shí)只有當(dāng)P0為1時(shí)候,才能夠使后級(jí)端導(dǎo)通。簡(jiǎn)單一點(diǎn)說(shuō)就是它要驅(qū)動(dòng)LCD顯示屏顯示就必須要有電源驅(qū)動(dòng),否則亮不了,而恰好P0口沒(méi)有電源,所以就要外接電源,接上電阻是起到限流的作用;如果接P1、P2、P3端口就不用外接電源和電阻了。 P0口是開(kāi)漏的,不管它的驅(qū)動(dòng)能力多大,相當(dāng)于它是沒(méi)有電源的,需要外部的電路提供,絕大多數(shù)情況下P0口是必需加上拉電阻的;5、51單片機(jī)的P0口用作數(shù)據(jù)和地址總線時(shí)不必加上拉電阻。 有些IC的驅(qū)動(dòng)能力并不強(qiáng),如果P0口作為輸入而加了不必要的上拉,有可能驅(qū)動(dòng)IC無(wú)法將其拉回到低電平,從而使輸入失敗! 如果是驅(qū)動(dòng)led,那么用1K左右的就行了。如果希望亮度大一些,電阻可減小,最小不要小于200歐姆,否則電流太大;如果希望亮度小一些,電阻可增大,增加到多少呢,主要看亮度情況,以亮度合適為準(zhǔn),一般來(lái)說(shuō)超過(guò)3K以上時(shí),亮度就很弱了,但是對(duì)于超高亮度的LED,有時(shí)候電阻為10K時(shí)覺(jué)得亮度還能夠用。通常就用1k的。對(duì)于驅(qū)動(dòng)光耦合器,如果是高電位有效,即耦合器輸入端接端口和地之間,那么和LED的情況是一樣的;如果是低電位有效,即耦合器輸入端接端口和VCC之間,那么除了要串接一個(gè)1——4.7k之間的電阻以外,同時(shí)上拉電阻的阻值就可以用的特別大,用100k——500K之間的都行,當(dāng)然用10K的也可以,但是考慮到省電問(wèn)題,沒(méi)有必要用那么小的。 對(duì)于驅(qū)動(dòng)晶體管,又分為PNP和NPN管兩種情況:對(duì)于NPN,毫無(wú)疑問(wèn)NPN管是高電平有效的,因此上拉電阻的阻值用2K——20K之間的,具體的大小還要看晶體管的集電極接的是什么負(fù)載,對(duì)于LED類負(fù)載,由于發(fā)管電流很小,因此上拉電阻的阻值可以用20k的,但是對(duì)于管子的集電極為繼電器負(fù)載時(shí),由于集電極電流大,因此上拉電阻的阻值最好不要大于4.7K,有時(shí)候甚至用2K的。對(duì)于PNP管,毫無(wú)疑問(wèn)PNP管是低電平有效的,因此上拉電阻的阻值用100K以上的就行了,且管子的基極必須串接一個(gè)1——10K的電阻,阻值的大小要看管子集電極的負(fù)載是什么,對(duì)于LED類負(fù)載,由于發(fā)光電流很小,因此基極串接的電阻的阻值可以用20k的,但是對(duì)于管子的集電極為繼電器負(fù)載時(shí),由于集電極電流大,因此基極電阻的阻值最好不要大于4.7K。 對(duì)于驅(qū)動(dòng)TTL集成電路,上拉電阻的阻值要用1——10K之間的,有時(shí)候電阻太大的話是拉不起來(lái)的,因此用的阻值較小。但是對(duì)于CMOS集成電路,上拉電阻的阻值就可以用的很大,一般不小于20K,我通常用100K的,實(shí)際上對(duì)于CMOS電路,上拉電阻的阻值用1M的也是可以的,但是要注意上拉電阻的阻值太大的時(shí)候,容易產(chǎn)生干擾,尤其是線路板的線條很長(zhǎng)的時(shí)候,這種干擾更嚴(yán)重,這種情況下上拉電阻不宜過(guò)大,一般要小于100K,有時(shí)候甚至小于10K。 根據(jù)以上分析,上拉電阻的阻值的選取是有很多講究的,不能亂用。 想信通過(guò)以上的說(shuō)明,你對(duì)單片機(jī)有了更深一層的了解了,那么,我們就對(duì)它進(jìn)行控制吧! 二、編寫(xiě)程序,讓夢(mèng)想從此實(shí)現(xiàn),實(shí)戰(zhàn)LED: 以下內(nèi)容有二進(jìn)制轉(zhuǎn)換,單位的換算,C語(yǔ)言基本函數(shù),C語(yǔ)言數(shù)值類型,這些緣緣都在開(kāi)頭就講過(guò)了,不懂的可以看看緣緣本系列的第一篇帖子:http://toutiao.com/i6272853945505284610/ 先看看原理圖,就是有8個(gè)LED共同接在正極上: 那么,再看看我們的P口是怎么回事: 那么,再看看我們的P口是怎么回事:
注意,所以的P口在定義管腳是從0開(kāi)始的,可不要記錯(cuò)了哦 為了方便實(shí)驗(yàn),我們就用P0口的那8個(gè)端口去操作這8個(gè)LED,P0口就是上節(jié)我們焊了電阻的那一部分: 1、先點(diǎn)亮第一個(gè)二極管 我們先看看P0口的如何去控制這個(gè)LED吧: 好了,我們來(lái)寫(xiě)寫(xiě)控制LED的這個(gè)程序: 首先,為了定義是上面那種管腳的類型,我們先寫(xiě)入頭文件,什么是頭文件呢?頭文件作為一種包含功能函數(shù)、數(shù)據(jù)接口聲明的載體文件,主要用于保存程序的聲明,而定義文件用于保存程序的實(shí)現(xiàn) ,是不是很難理解呢,那就教你個(gè)方法,相當(dāng)于頭文件就是個(gè)稱呼,比如,你稱呼緣緣,緣緣我就知道你在叫緣緣了,所以,在51單片系統(tǒng)中,頭文件就是定義了51單片機(jī)的存儲(chǔ)類型,端口狀態(tài),功能結(jié)構(gòu)與數(shù)據(jù)使用類型,只要是與51單片有關(guān)系的,都會(huì)在頭文件中體現(xiàn),那么如何在Keil文件中體現(xiàn)呢,我們用如下的方法進(jìn)行: #include < reg52.h=""> 怎么樣,簡(jiǎn)單吧,你只要寫(xiě)上這一句,關(guān)于單片內(nèi)部的部分就不用管了,接下來(lái)我們寫(xiě)上這么兩句話: #define uchar unsigned char #define uint unsigned int 這兩句話的意思就是把unsigned char這種類型的數(shù)值用uchar這種名字替代,這樣是為了方便寫(xiě)些,對(duì)于咱們英文不好的小白們來(lái)說(shuō),這絕對(duì)是一個(gè)值得稱贊的好注意,寫(xiě)完了這兩個(gè),我們要操作的是P0鎖存器的第一根端口,即P0.0,我們現(xiàn)在就把它定義一下吧,用一個(gè)名字替代它: sbit D=P0^0;(這里的D是個(gè)名稱的意思,如果不嫌麻煩,當(dāng)然也可以寫(xiě)成緣緣的拼音的,因?yàn)镃語(yǔ)言中不執(zhí)行漢字,所以就只能寫(xiě)拼音了,親們,以后記著哦) 那么,到這里,我們先說(shuō)下上面的define與這里的sbit的區(qū)別: define是泛指,即在程序中出現(xiàn)的與此相關(guān)的全部的都是這個(gè)類型,主要指數(shù)值類型,其意義是宏定義,而sbit是指特指,也就是針對(duì)某一個(gè),在程序中常用于定義端口。 到現(xiàn)在,我們基本上明確了這些,我們就把上面的內(nèi)容匯總到一起,這里記住C語(yǔ)言的幾個(gè)特點(diǎn): 1、所有的標(biāo)點(diǎn)符號(hào)全是英文的,如果你在后面弄個(gè)中文的標(biāo)點(diǎn)符號(hào),這肯定編譯不過(guò)去。 2、用于注釋時(shí),即不讓這句話在程序中執(zhí)行時(shí),可以前面打上英文的//,如果要注解一段內(nèi)容,方法是在最前面寫(xiě)上英文符號(hào)/*,后面寫(xiě)上*/。 3、在所有的程序中,只包含一個(gè)主程序,也就是main()函數(shù),其寫(xiě)法是: void main() { 內(nèi)容 } 4,一個(gè)大括號(hào)算是一個(gè)完整的程序,常寫(xiě)在函數(shù)的后邊,里面會(huì)包含若干個(gè)子程序,也是有大號(hào)的哦,意思是會(huì)執(zhí)行其中的內(nèi)容。 5、一條單獨(dú)的程序在結(jié)束時(shí),以英文符號(hào);結(jié)尾,含大括號(hào)的除外。 講了這么多,是不是想寫(xiě)個(gè)真正控制LED的程序,那好,跟我一起來(lái)吧: #include < reg52.h="">//有寫(xiě)< reg51.h="">,其效果是一樣的 #define uchar unsigned char #define uint unsigned int sbit D=P0^0; void main() { D=0; } 現(xiàn)在我們完成了程序的書(shū)寫(xiě),我們編譯下吧,看看,有錯(cuò)誤嗎,沒(méi)有,對(duì)吧,那好吧,用前面教的方法燒錄進(jìn)去吧,是不是奇跡出現(xiàn)了,這時(shí),你覺(jué)得單片機(jī)難嗎,不難對(duì)嗎?這可不是我說(shuō)的 2、分別依次點(diǎn)亮其它的二極管 我們即然能把一個(gè)LED點(diǎn)亮,當(dāng)然其它的就不在話下了,我們只對(duì)上面的程序做一個(gè)小小的改動(dòng)就行了,也就是更改sbit D=P0^0;最后面的這個(gè)數(shù)字,假設(shè)我們讓第二個(gè)亮,就改成sbit D=P0^1,怎么樣,簡(jiǎn)單吧,親們,自己試試,把其它的都點(diǎn)亮吧! 3、點(diǎn)亮某幾個(gè)二極管 只要能點(diǎn)亮一個(gè)LED,那么剩下就不是問(wèn)題了,于是我們?cè)俣嘤诙x幾個(gè)不就行了,假高我要點(diǎn)亮1,3,5,7該怎么做呢,跟著緣緣一起寫(xiě)起來(lái)吧: #include < reg52.h=""> #define uchar unsigned char #define uint unsigned int sbit D1=P0^0; sbit D2=P0^2; sbit D3=P0^4; sbit D4=P0^6; void main() { D1=D2=D3=D4=0; } 4、總線法點(diǎn)亮 總線是什么意思呢,親們,看看這個(gè)說(shuō)明吧: 我們用程序試驗(yàn)一下吧: #include < reg52.h=""> #define uchar unsigned char #define uint unsigned int void main() { P0=0xfc; } 好了,那么親們,發(fā)揮你的想像吧,自己亂定義幾個(gè),讓燈亮吧! 5、延時(shí)講解 以下的延時(shí)都會(huì)用到一個(gè)知識(shí)點(diǎn),就是機(jī)器周期,也就是單片機(jī)在處理一個(gè)數(shù)值時(shí)用的時(shí)間,比如,讓它加一下,也就是加個(gè)1,那么它就會(huì)費(fèi)一個(gè)機(jī)器周期的時(shí)間去處理這個(gè)事情,那么如何去算呢,一個(gè)機(jī)器周期是晶震的12分頻,那么,如果我們用12M的晶震的話,換算的機(jī)器周期就是12(晶震)×1/12=1US,為什么這么算呢,因?yàn)?2M晶震的的意思是在1秒的時(shí)間內(nèi)跳動(dòng)了12000000次,(那么這個(gè)數(shù)是多少呢,自己算算吧,緣緣很懶的,就猜了下,是12M(兆)吧?。┠敲淳д鹈刻?2下,這個(gè)單片機(jī)就會(huì)處理一個(gè)事務(wù),所以在1秒內(nèi)就會(huì)處理1000000,那么1次是多少呢,我們就用前面學(xué)過(guò)的公式進(jìn)行轉(zhuǎn)換吧,我們知道1S=1000MS,那么1000000次/1000=1000次,也就是說(shuō)在1MS內(nèi),單片機(jī)執(zhí)行了1000次,通過(guò)MS的轉(zhuǎn)換得知1MS=1000US,那么1000次/1000就成變成了1次了,所以我們得出一個(gè)結(jié)論,就是單片機(jī)執(zhí)行一次任務(wù)的時(shí)間是1US。(這是為了方便計(jì)算用的是12M的晶震,如果是其它的晶震,就不是這個(gè)值了,但算法是一樣的。) 為了方便計(jì)算,以下延時(shí)按12M晶震計(jì)算: 對(duì)于延時(shí),常用的有While循環(huán)法延時(shí)法,for嵌套延時(shí)法,中斷延時(shí)法,還有IF延時(shí)法,下面我們分別去看看: ⑴while循環(huán)法: While循環(huán)是單片程序中經(jīng)常用到的一個(gè)程序,它的書(shū)寫(xiě)規(guī)則是: while(表達(dá)式) { 執(zhí)行內(nèi)容 } 一般地,在延時(shí)程序中時(shí),沒(méi)有用到后面的執(zhí)行程序,所以通常的寫(xiě)法是: a=50000; while(a--); 是什么意思呢,就是先讓a等于一個(gè)數(shù),這個(gè)數(shù)是很大的,原因后面會(huì)有說(shuō)明,當(dāng)然,這個(gè)a要在前面定義的,然后進(jìn)入while循環(huán)中,在while中,1表示真,0表示假,所以,當(dāng)while后面括號(hào)內(nèi)的數(shù)值變成0時(shí),就會(huì)跳出這個(gè)循環(huán),那么,當(dāng)a=50000的時(shí)候,要在while中減上多少次才能跳出循環(huán)呢,答案就是50000次,我們說(shuō)過(guò)機(jī)器在處理一次數(shù)值,即執(zhí)行a減一下,就是-1的過(guò)程中,會(huì)占用1個(gè)機(jī)器周期,即1US,那么執(zhí)行50000次是不是就是50000*1,就等于50000US,那么換算成毫秒是多少呢,就是50000/1000=50MS(毫秒),再換算成秒是多少呢,即50/1000=0.05秒,所以,如果在程序中加入這個(gè)的話,就會(huì)延時(shí)0.05秒,如果再想定得短了就讓a的值小一些,想改得大一點(diǎn)了,就讓a的值大一些,但有點(diǎn)要注意,因?yàn)閱纹瑱C(jī)內(nèi)部空間決定,只能處理65535這么大的數(shù),超過(guò)這個(gè)數(shù),將先減掉65535,用減剩下的數(shù)去賦值,親們,可不要弄錯(cuò)哦。 那么,我們有沒(méi)有讓它再延長(zhǎng)一下呢,這個(gè)很好辦的,a=50000是0.05秒,如果我們想要得到0.10秒該如何使用呢,那就是再多加一次這樣的延時(shí)函數(shù),親們,你們明白了嗎? a=50000; while(a--); a=50000; while(a--); 這樣就做到了延時(shí)0.10秒的功能了,是不是很簡(jiǎn)單??! ⑵for延時(shí)法: for循環(huán)是單片程序中經(jīng)常用到的另一種延時(shí)程序,它通常以雙for嵌套的方式出現(xiàn),下面我們看看它的結(jié)構(gòu)吧: For (表達(dá)式1;表達(dá)式2;表達(dá)式3) { 語(yǔ)句(內(nèi)部可為空)} 執(zhí)行過(guò)程: 1.求解一次表達(dá)式1. 2.求解表達(dá)式2,若其值為真(非0 即為真),則執(zhí)行for中語(yǔ)句。然后執(zhí)行第3步。否則結(jié)束for 語(yǔ)句,直接跳出,不再執(zhí)行第3步。 3.求解表達(dá)式3. 4.跳到第2步重復(fù)執(zhí)行。 什么意思呢,我們用一個(gè)例子來(lái)說(shuō)明這個(gè)問(wèn)題: 如:for(j=110;j>0;j--); 第一步:進(jìn)入for循環(huán),這時(shí),看到了把110這個(gè)賦給了j,這時(shí),j的值是110,然后執(zhí)行第二步; 第二步:判斷j是不是在于0了,通過(guò)第一步我們得知j是110,110當(dāng)然比0大了,這時(shí)就執(zhí)行第三步; 第三步;當(dāng)?shù)诙脚袛嗤炅说臅r(shí)候,這時(shí)我們看到j(luò)- -,- -也就是減1, 那么當(dāng)j-1后是多少呢,是109對(duì)吧,這里就會(huì)返到前面第二步進(jìn)行繼續(xù)判斷,看j是不是比0大,如果還是0大,那么就會(huì)再次執(zhí)行第三步,如此循環(huán),那么什么時(shí)候不執(zhí)行了呢,也就是當(dāng)j變成0時(shí),不大于0了,這個(gè)程序就結(jié)束了,那么這條語(yǔ)句執(zhí)行完需要多長(zhǎng)時(shí)間呢,就是110US,親們,懂了嗎? 上面的情況只是在沒(méi)有其它程序的情況下做的延時(shí),如果有其它后綴程序時(shí),就會(huì)在j- -一次的情況下去執(zhí)行其它的程序,如下面這個(gè)程序: for(j=200;j>0;j--) { a++; } 我們看到,當(dāng)j每減一次時(shí),a就會(huì)加一次,那么這樣下來(lái),j=0時(shí),a等于多少呢,答案是200,如果,我們?cè)倥獋€(gè)跟上面一樣的延時(shí)程序會(huì)怎么樣呢,我們?cè)囋嚳窗桑ㄎ野裫換成x了,其實(shí)不管是j還是x,它們只是一種名稱而已): for(x=500;x>0;x--) for(y=200;y>0;y--); 注意,當(dāng)兩個(gè)for套在一起時(shí),前面一個(gè)沒(méi)有分號(hào)哦,后面的相當(dāng)于是它的了程序,好了,我們分析一下這個(gè)程序吧: 通過(guò)前面的程序我們得知,當(dāng)執(zhí)行時(shí),先進(jìn)入第一條語(yǔ)句,我們看到,給x賦值是500,這時(shí)x是大于0的,所以進(jìn)行了x減1的操作,x減1后就是499了,那么這里會(huì)執(zhí)行下面的程序,通過(guò)前面的講解,這條語(yǔ)句不能執(zhí)行的唯一條件就是y=0,即當(dāng)中的那條程序不成立時(shí)才會(huì)跳出來(lái),對(duì)于這樣一條語(yǔ)句,前面說(shuō)過(guò),y會(huì)減200次,所以上面的這條語(yǔ)句的含義就是x減1下,y就會(huì)減上200次,那么如果當(dāng)x也不執(zhí)行時(shí),唯一的條件就是判斷x不大于0,即x減完后等于0時(shí),就會(huì)跳出整個(gè)for循環(huán),所以得到x是減了500次才跳出這個(gè)循環(huán)的,那么這個(gè)循環(huán)用了多長(zhǎng)時(shí)間呢,我們知道x減一次,y就會(huì)減200次,y減200次占用的時(shí)間是200US,那么執(zhí)行了500次以后是多少呢,就是x值與y的值相乘,即為500*200=10000US,如果親們不好理解時(shí),可以這樣想下,y就是延時(shí),x是指延時(shí)多少次,這樣下來(lái)延時(shí)的效果是很明顯的。 我們前面用了很長(zhǎng)的片幅去講解for循環(huán)的原理,那么在程序中是怎么樣用的呢,一般以函數(shù)的形式出現(xiàn): void delayms(unsigned int z) { unsigned int i,j; for(i=z;i>0;i--) for(j=110;j>0;j--); } 這是一個(gè)延時(shí)函數(shù),現(xiàn)在我可以看到,delayms這個(gè)就是這個(gè)函數(shù)的名稱,就相當(dāng)于大家叫我緣緣一樣,這個(gè)程序的時(shí)間是沒(méi)有定義的,即 i=z,也就是當(dāng)我們?cè)谝院蟮某绦蛑姓{(diào)用時(shí),我們要寫(xiě)上延時(shí)多少次就行了,那么在程序中怎么調(diào)用呢,很簡(jiǎn)單: delayms(20); 記得加上;號(hào)哦,那么這個(gè)延時(shí)程序的延時(shí)是多長(zhǎng)時(shí)間呢,就是20*110=2200US。 剛才我們用了減的,那么能用加的嗎,答案是肯定的,這里只做一個(gè)簡(jiǎn)單的寫(xiě)法,原理是相通的哦: for(x=0,x<> 關(guān)于for就這么一回事,親們,一定懂得怎么算時(shí)間哦。 ⑶中斷延時(shí):因?yàn)樯婕暗街袛啵栽诤竺娴闹袛喹h(huán)節(jié)中專門(mén)進(jìn)行講解,親們可不要錯(cuò)過(guò)哦。 ⑷if延時(shí):if是單片機(jī)程序中用判斷用得最多的,if延時(shí)一般與while一起套用,方式如下: if(表達(dá)式) { 執(zhí)行內(nèi)容(可為空) } 所以我們用if做為延時(shí)時(shí),加上while,我們得知while中,1為真,0為假,所以程序這樣寫(xiě): x=1; while(x) { x++; if(x=501) x=0; } 那么這樣的延時(shí)時(shí)間是多少呢,那就是500-1=500US,因?yàn)閣hile為0時(shí)進(jìn)不去,所以我們讓定義x的值為1,這地就會(huì)在while循環(huán)中一直執(zhí)行x加1的程序,我們看到,當(dāng)判定x的值達(dá)到501時(shí),這時(shí),又給X賦值為0了,在while中,X為0就會(huì)跳出來(lái),所以這樣就會(huì)達(dá)到延時(shí)目的。 以上就是延時(shí)的一些方法,大家可以自由應(yīng)用哦。 ※ 以上就是對(duì)延時(shí)的講解說(shuō)明,可以看出晶震頻率對(duì)延時(shí)有著很大的影響,換而言之,如果晶震頻率越高,單片機(jī)處理速度也就越快,例如:12MHZ下處理速度是1US,那么如果是24MHZ下是多少呢,12*1/24=0.5US就是原來(lái)的一半,也就是0.5US了,那么如果是11.0592MHZ的呢,即為12*1/11.0592=1.085US了,所以延時(shí)程序是根據(jù)晶震的頻率來(lái)調(diào)節(jié)的,親們,懂了嗎? 6、讓二極管亮一下滅一下 這個(gè)很簡(jiǎn)單吧,我們知道0就會(huì)亮,是1就會(huì)滅,那么加上延時(shí)就行了,緣緣笨,就用最簡(jiǎn)單的吧,我們用前一個(gè)程序做下例子哦: #include < reg52.h=""> #define uchar unsigned char #define uint unsigned int uint a; sbit D=P0^0; void main() 如有疑問(wèn),可把問(wèn)題發(fā)送給“云漢電子社區(qū)”微信公眾號(hào)平臺(tái),我們會(huì)及時(shí)回復(fù),關(guān)注公眾號(hào)可閱讀更多緣緣學(xué)單片系列教程! |
|