版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、精心整理相信很多愛好電子的朋友,對單片機(jī)這個詞應(yīng)該都不會陌生了吧。不過有些朋友可能只聽說他叫單片機(jī),他的全稱是什么也許并不太清楚,更不用說他的英文全稱和簡稱了。單片機(jī)是一塊在集成電路芯片上集成了一臺有一定規(guī)模的微型計算機(jī)。簡稱為:單片微型計算機(jī)或單片機(jī)(SingleChipComputer)。單片機(jī)的應(yīng)用到處可見,應(yīng)用領(lǐng)域廣泛,主要應(yīng)用在智能儀表、實時控制、通信、家電等方面。不過這一切都沒什么關(guān)系,因為我(當(dāng)然也包括任何人)都是從不知道轉(zhuǎn)變成知道的,再轉(zhuǎn)變成精通的?,F(xiàn)在我只想把我學(xué)習(xí)單片機(jī)的經(jīng)歷,詳細(xì)地講敘給大家聽聽,可能有些大蝦會笑話我,想:那么簡單的東西還在這里賣弄。但是你錯了,我只是把我
2、個人學(xué)習(xí)的經(jīng)歷講述一遍而已,僅僅對那些想學(xué)習(xí)單片機(jī),但又找不到好方法或者途徑的朋友,提供一個幫助,使他們在學(xué)習(xí)過程中,盡量少走些彎路而已!?首先,你必須有學(xué)習(xí)單片機(jī)的熱情,不是說今天去圖書館看了一個下午關(guān)于單片機(jī)的書,而明天玩上半天,后天就不知道那個本書在講什么東西了。還是先說說我吧,我從大二的第一個學(xué)期期末的時候才開始接觸單片機(jī)但在這之前,正如上面所說的:我知道有種芯片叫單片機(jī),精心整理但是具體長成什么樣子,卻一點也不知道!看到這里很多朋友一定會忍不住發(fā)笑。嘿嘿,你可千萬別笑,有些大四畢業(yè)的人也同樣不知道單片機(jī)長成什么樣子呢!而我對單片機(jī)的癡迷更是常人所不能想象的地步,大二的期末考試,我全放
3、棄了復(fù)習(xí),每當(dāng)室友拿著書在埋頭復(fù)習(xí)的時候,我卻捧著自己從圖書館借的單片機(jī)書在那看,雖然有很多不懂,但是我還是堅持了下來,當(dāng)時我就想過,為了單片機(jī)值不值得我這樣去付出,或許這也是在一些三流學(xué)校的好處吧,考試掛科后,明年開學(xué)交上幾十元一門的補(bǔ)考費(fèi),應(yīng)該大部分都能過了。于是,我橫下一條心,堅持看我的單片機(jī)書和資料。?當(dāng)你明白了單片機(jī)是這么一回事的時候,顯而易見的問題出來了:我要選擇那種語言為單片機(jī)編寫程序呢?這個問題,困擾了我好久。具體選擇C51還是A51呢?匯編在我們大二之前并沒有開過課,雖然看著人家的講解,很容易明白單片機(jī)的每一時刻的具體工作情況,但是一合上書或者資料,自己卻什么也不知道了,根本
4、不用說自己寫程序了。于是,我最終還是決定學(xué)C51,畢竟C51和我們課上講的C語言,有些類似,編程的思想可以說是相通的。而且C51還有更大的優(yōu)點就是編寫大程序時的優(yōu)越性更不言而喻,當(dāng)然在那時,我并沒有想的那么深遠(yuǎn),C51的特精心整理點,還是在后來的實踐過程中,漸漸體會到的!朋友如果你選擇了C51,那么請繼續(xù)往下看,如果你選擇了A51,那么你可以不要看了!因為下面講的全是C方面的,完全在浪費(fèi)你的時間!??呵呵二?第二,既然你想學(xué)好單片機(jī),你必須得舍得花錢,如果不買些芯片回來自己動手焊焊拆拆的(但是在后期會介紹給大家一個很好用的硬件仿真軟件,并不需要你用實驗板和仿真器了,直接在你的PC上完成,但是軟
5、件畢竟是軟件,從某個特定的意義上來說是并不能代替硬件的),即使你每天捧著本書,把那本書翻爛,也永遠(yuǎn)學(xué)不會單片機(jī)的!剛接觸單片機(jī)的朋友,看了資料,一定會對以下幾個詞見的比較多,但是具體的概念還是比較模糊,現(xiàn)作如下說明:(1)編程器編程器是用來燒單片機(jī)芯片的,是把HEX或者BIN文件燒到單片機(jī)ROM里的,供單片機(jī)運(yùn)行的。(2)實驗板實驗板是專為初學(xué)者根據(jù)某些要求而特做的板,一般上面就有一個單片機(jī)的最小系統(tǒng),使用者只需寫好程序,燒好芯片,放到上面加以驗證的這么一個工具。有了實驗板,對與初學(xué)者來說,省去了焊個最小系統(tǒng)的麻煩。但是對于電子開發(fā)人員來說,作用并不是很大(3)仿真器仿真器是直接把HEX或者B
6、IN文件暫時放在一個芯片里,再通過這個芯片的引腳連接到實驗板或者系統(tǒng)上工作。這樣以來,可精心整理以省去了來回插拔芯片帶來的不必要麻煩。?我一開始也不知道上面3個的概念和作用,嘿嘿,原本想買個實驗板(不想焊板,因為不可能為了點亮幾個流水燈,而去焊個單片機(jī)的最小系統(tǒng))的,可是結(jié)果,確和我想的正好相反,人家出售的是編程器。等貨物寄到后,才知道自己搞錯了!汗。嘿嘿?,F(xiàn)在想想實在是又氣又笑。我花了160大樣買了個編程器(很不幸的是,這個編程器更本用不了,一燒芯片,芯片就燒壞了)把我給氣的,這個編程器,現(xiàn)在還躺在我的抽屜里呢不過,現(xiàn)在想想,唯一讓我覺得欣慰的是,那個老板每次能解答我的問題,連那種超級幼稚的
7、問題,他也能不嫌麻煩地盡量幫我解答!這點讓我很感動!?第三,想學(xué)單片機(jī)的必需品-pc。因為寫程序,編譯或者是仿真都是通過PC完成的。如果沒有PC,什么也做不了!有了PC最好還要可以上網(wǎng),因為如果你沒有可以和你交流單片機(jī)的人,遇到自己解決不了的問題,一直都想不通,那么估計你學(xué)習(xí)單片機(jī)的熱情就會隨著時間的推移而慢慢耗盡。如果你能上網(wǎng)通過論壇或者QQ群,問題就很快得到解決。這樣的學(xué)習(xí)效率一定很高!真正的高手是從論壇中泡出來的!?有了上述3個條件后,你就可以開始學(xué)你的單片機(jī)了。但是,真的做起來并沒有我所說的那么簡單。你一定會遇到很多很多的問題。比如精心整理為了讓單片機(jī)實現(xiàn)某個功能,你可能不知道怎么去寫
8、某個程序?;蚴悄憧炊速Y料上某個相似的程序,你自己卻寫不出來。遇到類似的情況,記住:千萬不要急噪,就行!二)?說了這么多了,相信你也看了很多資料了,手頭應(yīng)該也有必備的工具了吧!(不要忘了上面講過幾個條件的哦)。那個單片機(jī)究竟有什么功能和作用呢?先不要著急!接下來讓我們點亮一個LED(搞電子的應(yīng)該知道LED是什么吧?我們在單片機(jī)最小系統(tǒng)上接個led,看我們能否點亮它!對了,上面也有好幾次提到過單片機(jī)最小系統(tǒng)了,所謂單片機(jī)最小系統(tǒng)就是在單片機(jī)上接上最少的外圍電路元件讓單片機(jī)工作。一般只須連接晶體、vcc、GND、RST即可,般情況下,AT89C51的31腳須接高電平。#includereg51.h
9、??/頭文件定義。或用#includeat89x51.h其具體的區(qū)別在于:后者定義了更多的地址空間。精心整理?/在Keil安裝文件夾中,找到相應(yīng)的文件,比較一下便知!?sbitP1_0=Pl八0;?/定義管腳?voidmain(void)while(l)P1_0=0;/低電平有效,如果把LED反過來接那么就是高電平有效?就那么簡單,我們就把接在單片機(jī)P1_0上的LED點亮了,當(dāng)然LED是低電平,才能點亮。因為我們把LED的正通過電阻接至VCC。?P1_0=0;類似與C語言中的賦值語句,即把0賦給單片機(jī)的P1_0引腳,讓它輸出相應(yīng)的電平。那么這樣就能達(dá)到了我們預(yù)先的要求了。while(l)語句只
10、是讓單片機(jī)工作在死循環(huán)狀態(tài),即一直輸出低電平。如果我們要試著點亮其他的LED,也類似上述語句。這里就不再講了。精心整理?點亮了幾個LED后,是不是讓我們聯(lián)想到了繁華的街區(qū)上流動的彩燈。我們是不是也可以讓幾個led依次按順序亮呢?答案是肯定的!其實顯示的原理很簡單,就是讓一個LED滅后,另一個立即亮,依次輪流下去。假設(shè)我們有8個LED分別接在P1的8個引腳上。硬件連接,在P1_1P1_7上再接7個LED即可。例程如下:#includereg51.hsbitP1_0=P1八0;sbitP11=P1八1;?sbitP1_2=2;sbitP13=P1八3;sbitP1_4=sbitP1_5=P1八5;
11、sbitP1_6=P1八6;sbitP1_7=P1八7;精心整理精心整理voidDelay(unsignedchara)unsignedchari;!=”for(i=0;i125;i+);/個;表示空語句,CPU空轉(zhuǎn)。從0加到125CPU大概就耗時1毫秒voidmain(void)while(1)精心整理精心整理P1_3= ;?Delay(250);P1_0=1;Pl_l=0;?Delay(250);P1_1=1;P1_2=0;?Delay(250);P1_2=1;P1_3=0;Delay(250);P1_4=0;?Delay(250);Pl_4=1;Pl_5=0;?Delay(250);P1
12、_5=1;P1_6=0;?Delay(250);P1_6=1;精心整理精心整理精心整理精心整理P1_7=0;Delay(250);P1_7=1;?sbit定義位變量,unsignedchara定義無符字符型變量a,以節(jié)省單片機(jī)內(nèi)部資源,其有效值為0255。main函數(shù)調(diào)用Delay()函數(shù)。Delay函數(shù)使單片機(jī)空轉(zhuǎn),LED持續(xù)點亮后,再滅,下一個LED亮。while(1)產(chǎn)生循環(huán)。三)?上面我們講了如何使led產(chǎn)生流動,但是你是否發(fā)現(xiàn)一個問題:寫的太冗長了!能不能再簡單點呢?可以!可以使用C51的內(nèi)部函數(shù)INTRINS.H實現(xiàn)。函數(shù)unsignedchar_crol_(unsignedcha
13、ra,unsignedcharn)可以使變量a循環(huán)左移n位,如果我們先給P1賦00000001那么當(dāng)n為1時,便會產(chǎn)生和上面一樣的效果!#includeintrins.h#includereg51.hvoidDelay(unsignedchara)unsignedchari;while(-a!=0)for(i=0;i125;i+);精心整理精心整理voidmain(void)unsignedcharb,i;b=0 xfe;:r(i=“1OptionsforTarget1-Target中填寫晶體的大小,Output中,在CreateHEXFiles前打上鉤,點確定。6.點Project一Rebu
14、ildAllTragetFiles,若提示?creatinghexfilefromXXX.?XXX-0Error(s),0Waring(s).表示編譯和生成HEX文件成功!接下來的就是把HEX文件燒到單片機(jī)中,或是仿真器上,看是否達(dá)到預(yù)先的目的!?嘿嘿!現(xiàn)在是否自己好有成就感了,如果讓你去做個流水彩燈,開發(fā)一個簡單的產(chǎn)品,只要加上驅(qū)動電路,就可以做出漂亮的流動彩燈精心整理了!到現(xiàn)在為止,你應(yīng)該知道單片機(jī)的功能有多強(qiáng)大了吧,如果單純的用數(shù)字電路或模擬電路的知識去設(shè)計一個流動彩燈,可能要花點工夫和時間才行,有了單片機(jī),那就不一樣了,你只要寫程序控制他就行!有人說過這樣一句話,也并不無道理的,學(xué)單片
15、機(jī),程序思想很重要!四)?呵呵,朋友!相信你的流水燈也做的不錯了吧,現(xiàn)在能玩出幾種花樣了?你可能會說,只要你想得到,想怎么流就怎么流!呵呵,是的。但是工程師們設(shè)計這么一個單片機(jī),并不是只為了讓它做流水燈的,那樣也太浪費(fèi)點了吧.??學(xué)過數(shù)字電路的朋友,一定動手做過8路或者6路的搶答器。用純粹的數(shù)字電路知識來做,自己設(shè)計電路,感到比較困難!搶答器上用的顯精心整理示器多為7段數(shù)碼管,這里我們來講講,如何用單片機(jī)讓數(shù)碼管顯示0-9。搶答器的實現(xiàn),我們放到后面再來探討,因為搶答器還涉及了鍵盤的內(nèi)容。8段數(shù)碼管分為共陰和共陽兩種。8段數(shù)碼管是由8個LED組成(還包括一個小數(shù)點)。若為共陽,則8個LED的陽
16、級是連接在一起的,同理若為共陰,則陰極連接在一起。8個LED對應(yīng)的標(biāo)號如下:(0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f;/0-9數(shù)字)?a?0?1?2?3?4?5?6?7?8?9?_?00111111,00000110,01001111,01011011?fb?gc?eJ.dp?d?般情況下,為了計算或取碼的方便,我們把a(bǔ)-dp依次接到單片機(jī)某個上的Px.0Px.7上。x表示0,1,2,3其中的一個。這樣我們只精心整理要給某個口,賦一個值,則相應(yīng)的LED段就被點亮,但是在硬件連接上要注意了:單片機(jī)可能不能直接驅(qū)動le
17、d,所以我們可以通過控制三級管的導(dǎo)通或截止,來控制LED的亮與滅!?如果我們把共陰的數(shù)碼管的adp依次接到單片機(jī)的P0.0P0.7上,注意:P0需接上拉電阻。何為上拉電阻,簡單的說,就是把電平拉高,以提高驅(qū)動能力。那么比如:P0=0X3F;則顯示為數(shù)字0。因為0X3F即為2進(jìn)制的00111111我們低位往高位數(shù),依次為11111100,其I/O的電平分別為高、高、高、高、高、高、低、低,即對應(yīng)的a-dp為亮、亮、亮、亮、亮、亮、滅、滅,由上圖我們可以看出g和dp段不亮其他段均亮,即為我們所看到的數(shù)字0字樣。其他的數(shù)字或字符,也同理可以得到。但是有些朋友就會問,那我們每取一個字模,豈不是很麻煩?
18、還有自己考慮高低電平什么的?呵呵,其實網(wǎng)上有很多LED取模軟件,如果有一定計算機(jī)編程語言的朋友,也可以試著自己寫個取模的程序,讓計算機(jī)為我們計算,諸如上述0X3F的數(shù)值。#includevoidDelay(unsignedchara)精心整理unsignedchari;while(-a!=0)voidmain(void)Po=0X3F;/顯示0?Delay(250);/延時P0=0X00;/短暫的關(guān)閉顯示,若不關(guān)閉,可能會造成顯示模糊不清。精心整理P0=0X06;/顯示1Delay(250);P0=0X00;./以下顯示數(shù)字2-F,略。?看到這里,想必大家一定可以把0-F顯示出來了吧!但是如果
19、要你顯示兩位數(shù),三位數(shù)呢?或許,有的朋友會這么想:在P0上接一個數(shù)碼管,再在P1上接個數(shù)碼管!但是,如果要顯示4位、5位的數(shù)字呢?那豈不是一塊AT8951都接不過來!難到就不能接4位或5位以上的嗎?肯定不是的!?說到這里,我們來講講數(shù)碼管的顯示方式,可分為兩種:動態(tài)掃描和靜態(tài)顯示上面我們所說的即為靜態(tài)顯示。但是如果我們采用動態(tài)掃描顯示,那么就可以解決上面的問題,即可以顯示多個數(shù)碼管了。上面我們所說的靜態(tài)顯示把數(shù)碼管的COM腳接至VCC或GND端,其他的接至PX精心整理上,這樣只要PX上輸出相應(yīng)的高低電平,就可以顯示對應(yīng)的數(shù)字或字符。但是如果我們采用動態(tài)掃描的方法,比如顯示6個數(shù)碼管,硬件連接可
20、以這樣解決:a-dp還是接至P0.0-P0.7上,還有6個COM腳再接至另外口的P2.0P2.5。P0作段選(控制數(shù)字字符)P2作位選(選通哪個數(shù)碼管導(dǎo)通)這樣我們控制P0和P2就可以控制6個數(shù)碼管了。但是,細(xì)心的朋友,會問這樣的問題:P2位選,是讓數(shù)碼管一個一個亮的,那還是不能控制6個一起亮或滅嘛?。堪讼胂牒孟笫菍Φ呐??怎么辦難道錯了??嘿嘿,問你個問題?黑夜里,拿著一支煙,在你面前快速的晃動,你會發(fā)現(xiàn)什么樣的現(xiàn)象?是不是原本不連續(xù)的點變成了一條看上去連續(xù)的曲線或者直線!再回過頭來,仔細(xì)想想我們的數(shù)碼管!原理是一樣的,你可別忘了,我們的單片機(jī)可是一個計算機(jī)哦,計算機(jī)的運(yùn)算速度,大家可想而知吧
21、!?這里再說說51單片機(jī)的機(jī)器周期和時鐘周期等概念。所謂機(jī)器周期就是訪問一次存儲器的時間。而1個機(jī)器周期包括12個時鐘周期。如果單片機(jī)工作在12M晶體下,那么一個時鐘周期為:1/12微妙。一個機(jī)器周期12*1/12=1微妙。如果晶體為6M,時鐘周期和機(jī)器周期各是多少呢精心整理?在匯編中,我們還要關(guān)心,指令執(zhí)行的機(jī)器周期長短不一,有1個周期、2個周期和4個周期等。?說著說著,跑了這么遠(yuǎn)了.還是回到原來的話題,如果我們把位選的P2也看作上面的“煙”一劃而過,那么我們看到的是不是6個一起亮或一起滅了!八哈哈,原來如此??記住,在任何某一時刻,有且只有一個數(shù)碼管能發(fā)光。如果你能把這句話理解了,你是真明
22、白我的意思了!朋友,現(xiàn)在給你個任務(wù),讓6個數(shù)碼管分別顯示1、2、3、4、5、6。看你自己可以搞定不?你自己先試著寫寫看咯#includereg51.hvoidDelay(unsignedchara)unsignedchari;while(-a!=0)精心整理for(i=0;i125;i+);voidmain(void)Po=0X06;/1的碼段P2=0 x01;/選通一位,或者P2_0=1;?Delay(20);/延時約20毫秒P0=0X00;/關(guān)閉顯示P0=0 x5b;/2的碼段00X0=Od(OS)=L%昱血四一裁駁/20X0=3d.:鉗咸/:99X0=Od00X0=Od(os):l=乙飛
23、d昱血四一裁駁/違oxo=3d鉗咸朋/:升X。=od00X0=0d(os)遼=l飛d昱血四一裁駁/迄oxo=3d精心整理P0=0 x6d;/5的碼段P2=0 x10;/選通一位,或者P2_4=1;?Delay(20);P0=0X00;P0=0 x7d;/6的碼段??P2=0 x20;/選通一位,或者P2_5=1;?Delay(20);:=0X00;精心整理(五)?相信大家一定見過數(shù)字時鐘,教學(xué)樓大廳一定有吧。每次路過,基本上只是隨便瞟上一眼,根本沒去想過他的工作原理什么。但是今天你也可以把他做出來了,是不是覺得自己很有成就感呢!呵呵!八?接上面所講的,我們先來做個簡單的實驗:在一個數(shù)碼管上輪流
24、顯示09這10個數(shù)字。還楞著干什么,快動手寫程序呀!好象有點難哦,要不先不要往下看了,嘿嘿,關(guān)機(jī)吧,自己先去想想,怎么樣?#includereg51.hunsignedcharcodeSEG_TAB二0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f;/0-9數(shù)字voidDelay(unsignedinta)/unsignedint定義為無符整形,取值范圍為0-32768精心整理unsignedchari;while(-a!=0)for(i=0;i125;i+);voidmain(void)unsignedchari;whil
25、e(l)for(i=0;i10;i+)精心整理?P0=SEG_TABi;/取SEG_TAB數(shù)組中的值?P2=0X01;?Delay(1000);?是不是顯示從09,跳動顯示,你的心是不是也跟著一起跳呀,離我們的目標(biāo)又邁進(jìn)了一步!不錯,繼續(xù)努力!?上面只顯示了一個數(shù)碼管的數(shù)字0-9,但是怎么樣要讓他顯示6個數(shù)字呢?這樣我們就可以做個時鐘出來玩玩了!還記不記得我們前面講過的P2的位選作用!嘿嘿,沒忘記就好!#includeunsignedcharhour=12,min=0,sec=0;精心整理unsignedcharcodeSEG_TAB=0 x3f,0 x06,0 x5b,0 x4f,0 x66
26、,0 x6d,0 x7d,0 x07,0 x7f,0 x6f;/0-9數(shù)字voidDelay(unsignedchara)unsignedchari;while(-a0)voiddisp(void)P0=SEG_TABsec%10;/顯示秒的個位精心整理P2=0X01;Delay(15);P2=0;P0=SEG_TABsec/10;/顯示秒的十位P2=0X02;Delay(15);P2=0;P0=SEG_TABmin%10;/顯示分的個位P2=0X04;Delay(15);P2=0;精心整理P0=SEG_TABmin/10;/顯示分的十位P2=0X08;Delay(15);P2=0;P0=SE
27、G_TABhour%10;/顯示時的個位P2=0X10;Delay(15);P2=0;P0=SEG_TABhour/10;/顯示時的十位P2=0X20;Delay(15);P2=0;精心整理voidmain(void)?while(1)disp();?編譯燒錄芯片后,觀察運(yùn)行現(xiàn)象。矣怎么一直顯示12:00:00,難道是時鐘沒有啟動?還是,另外的原因呢?哦,原來是3個變量sec,min,hour初始化后,其值一直沒有改變!那我們怎么樣才能讓他改變數(shù)值呢?有的朋友一定會這么認(rèn)為:讓秒個位延時1秒,后加1,而秒十位延時10秒后,再加1,一直加到6,分個位加1,依次類推.這樣的想法是不錯,但是朋友你有
28、沒有想過C語言的一般延時(除非你精心整理把他放到中斷里)極不精確!這樣累計下來,一天24小時的誤差,肯定很大很大,我曾經(jīng)也用延時的方法寫過時鐘,1個小時誤差8秒,那是個什么概念!一天24小時就要24*8=192,約為3分鐘,一個月就是10分鐘.有沒有其他的方法可以改進(jìn)些呢?有!這里就要涉及到單片機(jī)中另一個比較重要的核心部分:單片機(jī)的中斷和定時器的運(yùn)用!想寫出比較精確(這里說的只的相對前面的做法而言比較精確而已,如果要做更加精確的時鐘,用時鐘芯片比較好點,常用的有DS12887和DS1302等)的時鐘程序,就一定要調(diào)用中斷和定時器。還是大家先看看教材和書吧,畢竟人家出的書,肯定比我要寫的系統(tǒng)多了
29、,下面我們再來簡單的講講!六)?什么是中斷呢?講個比較通俗的例子:比如你正在家中看電視,突然電話響了你的第一反應(yīng)是什么?是不是先跑過去接電話!接完電話后,繼續(xù)看電視。這就是個中斷的例子,中斷是由電話引起了,你跑過去就是響應(yīng)中斷,接電話就是中斷的處理!接完電話后,接續(xù)看電視,精心整理即恢復(fù)中斷,等待下個中斷的到來?但是這個好象和單片機(jī)沒什么聯(lián)系呀?有的朋友或許會這樣疑問。是的。單片機(jī)當(dāng)然不會看電視了,也不會接電話了!八但是,類比一下:比如單片機(jī)正在執(zhí)行某個任務(wù),突然要有更重要的事件,要求單片機(jī)響應(yīng)單片機(jī)就會應(yīng)答響應(yīng),去執(zhí)行更為重要的任務(wù)(中斷處理),原來的任務(wù)就繼續(xù)等待(現(xiàn)場的保護(hù))。執(zhí)行完更重
30、要的任務(wù)后,回到中斷的入處,繼續(xù)執(zhí)行原來的任務(wù)(現(xiàn)場中斷的恢復(fù))。51系列的單片機(jī)共有5個中斷源,分別為:外中斷0、定時器T0中斷、外中斷1、定時器T1中斷、串中斷。????或許,有些朋友已經(jīng)大概領(lǐng)會了其中的意思,有些朋友還迷迷糊糊。不過不要緊,我們繼續(xù)往下看,下面我們來講講單片機(jī)的定時器是什么?如何工作的?定時器,大家從字面上就可以看出其大概的意思吧?簡單的說:就是起定時作用!也就是讓單片機(jī)計數(shù)。定時器分為:方式0方式1、方式2和方式3等4種工作方式。有些朋友一定會問:定時器如何啟動?風(fēng)扇的定時器,相信大家一定都用過吧!但是單片機(jī)的定時器,該如何啟動呢?總不該也用手一擰定時器吧!八當(dāng)然不是,
31、我們只要給單片機(jī)一些指令,就可以啟動定時器了!下面我們就定時器0,來說精心整理說怎么啟動定時器0TMOD=0X01;/設(shè)置定時器0工作方式0TH0=(655365000)/256;/載入高8位初值TL0=(655365000)%256;/載入低8位初值TR0=1;?/啟動定時器?八,簡單吧,這樣我們就可以把定時器啟動了。其中TMOD為T/C方式控制寄存器:D7D6D5D4D3D2D1D0?_?_?GATEC/T?M1?M0?GATEC/TM1M0?精心整理精心整理?T/C1?T/C1?丄/丄?T/C0?C/T就是counter(記數(shù)器)和timer(定時器)的選擇位,若值為1,則作計數(shù)器用。為
32、0,則為定時期用!GATE為門控位。M1和M0工作方式的選擇:若M1=0;M0=0則為方式0:13位定時/記數(shù)器。若M1=0;M0=1則為方式1,16定時/記數(shù)器。若M1=1;M0=0則為方式2,自動裝載8位定時/記數(shù)器。若M1=1;M0=1則為方式3,只適用于T/C0,2個8位定時/記數(shù)器。?說了一大堆,感到有點困惑了吧。那我們還是來說說上面的。TMOD二0X01;/至于為什么是0X01,大家看:我們選擇的是定時器0方式0,所以T/C1全為0,而T/C0的M1為0。M0為1,所以D0-D7為0X01;0X01表示的是16進(jìn)制數(shù),這個大家應(yīng)該都知道吧!還有D0-D7表示的是2進(jìn)制數(shù)。還需要轉(zhuǎn)換
33、一下!?TH0=(65536-5000)/256;/載入高8位初值。若在12M晶體下,定時5000微秒,即為5毫秒;但是如果不是在12M下,那又該怎么計算了呢?如果是11.0592M呢?還記不記得,我們前面講過的機(jī)器周期和時鐘周期的概念?八忘了,還是看看前面吧!呵呵!沒事,學(xué)習(xí)嘛,忘精心整理了再翻翻書,看看就可以了!其實上訴的5000=1*C很顯然C=5000,但是如果是11.0592M那么就不是1了,應(yīng)該是1.085了,那么5000=?1.085*C,則C就為5000/1.085=?具體多少,大家自己去算算吧?同理TL0也是一樣的!但是,細(xì)心的朋友會發(fā)現(xiàn)網(wǎng)上或者是資料上的TH0,TL0并不是
34、和上面一樣的,而是直接TH0=0XEC;TL0=0X78是不是和上面的一樣的,別忘了單片機(jī)也是計算機(jī)的一種哦。用C的話,直接寫上計算公式就行,計算就交給單片機(jī)完成。?TR0=1;這句就是啟動定時器0,開始記數(shù)!哦,還有一點,有些朋友會問,你是65536是哪里來的呢?呵呵你可別忘了:設(shè)置定時器0?工作方式0是16位的(2的16次方是多少,自己算算就知道了)簡單吧?但是如何和中斷一起使用呢?請繼續(xù)看下面的講解!TMOD=0X01;/設(shè)置定時器0工作方式0TH0=(65536-5000)/256;/載入高8位初值TL0=(65536-5000)%256;/載入低8位初值TR0=1;?/啟動定時器精心
35、整理?EA=1;/開總中斷ET0=1;/開定時器中斷。若為0則表示關(guān)閉!?這樣我們,就初始化定時器T0和中斷了,也就是定時器滿5毫秒后,產(chǎn)生一次中斷。產(chǎn)生中斷后,我們怎么處理呢?嘿嘿!仔細(xì)想想?每次中斷后,我們可以讓一個變量自加1,那么200次中斷后,不就是1秒的時間了嗎?比起上面我們說的延時來出來是不是更加精確多了呢?那是肯定的!但是想想1秒種的時間就讓單片機(jī)產(chǎn)生那么多次的中斷,單片機(jī)會不會累著呢?恩,那么不好。如果在12M的晶體下,T0每次中斷不是可以產(chǎn)生最多65.336毫秒的時間嗎?那么我們讓他每50毫秒中斷一次好了!這樣我們就20次搞定一秒的時間了!爽?好了,講了那么多,現(xiàn)在我們來寫個
36、時間的程序吧!八#include精心整理精心整理#defineHI?(65536-50000)/256)#defineLO?(65536-50000)%256)#define_TH0_TL0_?(65536-50000)#defineM?20?/(1000/25)/*1*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*%X*X*%X*vl*vt*X*X*vt*vt*1*X*vt*vt*vt*vt*vl*vt*vt*X*vt*vt*vt*vt*vt*vt*X*vt
37、*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*/*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*X*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*1*vt*vt*vt*vt*vt*vt*vt*vt*/*t*t*t*t*t*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*/unsignedhou=12,min=0,sec=0;unsigned
38、charSEG_TAB_B=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x82,0 xf8,0 x80,0 x90;/0-9數(shù)字unsignedcharSEG_TAB_A=0 x40,0 x79,0 x24,0 x30,0 x19,0 x12,0 x02,0 x78,0 x00,0 x10;/0.-9.數(shù)字/vt*vt*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt
39、*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*/*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*X*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*/*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T
40、*T*T*T*T*/voidDelay(unsignedchara)/延時程序a*lMSunsignedcharj;?w0):(j=0;jT*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*X*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*/*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*
41、T*T*/voidDisp(void)/數(shù)碼管顯示P2_0=1;P1=SEG_TAB_Bhou/10;?Delay(5);P2_0=0;P2_l=1;Pl=SEG_TAB_Ahou%10;Delay(5);P2_1=0;P2_2=1;P1=SEG_TAB_Bmin/10;?Delay(5);?P2_2=0;P2_3=1;P1=SEG_TAB_Amin%10;?Delay(5);P2_3=0;P24=1;llSEG_TAB_Bsec/10;?Delay(5);?P2_4=0;P2_5=1;P1=SEG_TAB_Bsec%10;?Delay(5);?精心整理精心整理P2_5=0;/vt*vt*vt
42、*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*/*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T
43、*T*T*T*T*T*T*T*T*T*T*T*X*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*/*t*t*t*t*t*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*/voidIsrTimerO(void)interrupt1using1?/定時50msstaticunsignedcharcount二0;/定義靜態(tài)變量countcount+;if(count二二M)count=0;?sec+;?if(sec=60)精心整理min+;sec=0;if(min=60)?hou+;min=0;?if(hou=24)?
44、hou=0;/if/if/if精心整理精心整理/vt*vt*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*/*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T
45、*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*X*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*/*4*4*4*4*T*T*T*T*T*T*T*T*T*T*T*T*T*T*/voidTimerOInit(void)/定時器0mod=0 x01;THO=HI;TL0=LO;TR0=1;ET0=1;EA=1;/vt*vt*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*v
46、t*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*/*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*X*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*
47、/*4*4*4*4*T*T*T*T*T*T*T*T*T*T*T*T*T*T*/void-TimerOInit();Disp();精心整理精心整理?簡單吧,還是有點看不懂哦,那你自己慢慢體會吧,如果你自己能寫個時鐘程序來,那么你的51單片機(jī)也就學(xué)了80%了。中斷和定時/記數(shù)器器,是個很重要的東西,幾乎用到單片機(jī)的地方都會涉及到中斷和定時!所以大家要好好掌握哦!U?哈哈,趕緊編譯HEX文件,搭好硬件,燒入單片機(jī),上電看看效果先!呵呵,現(xiàn)在你應(yīng)該有成就感了吧,想不到一個時鐘居然那么簡單,嘿嘿!但是問題來了!時鐘雖然做出來了,但是他的精度怎么樣呢?一兩個小時,或許看不出什么誤差,但是一天或者一年呢?暈
48、,我的天呀,要是按年來算的話,那這個時鐘根本沒有實用價值!人家都說用C寫不出,精度高的時鐘程序來的!是不是有點后悔了,去學(xué)匯編吧!但是既然選擇了C,那么就不要后悔!嘿嘿,想想C的高級語言,怎么會輸給匯編呢八呵呵!看下面這段代碼:staticunsignedcharcount=0;TR0=0;?TL0+=(_TH0_TL0_+9)%256;?TH0+=(_TH0_TL0_+9)/256+(char)CY;?TR0=1;count+;?在中斷處理服務(wù)程序中,我們加入上面的代碼。TR0=0;先關(guān)閉定時器T0,然后重新給TH0和TL0賦值,再開啟TR0=1;燒入單片機(jī)看看效果,怎么樣,你第一次精確多了
49、吧。但是還是有誤差!郁悶!為什么呢?那是硬件造成的誤差,我們可以用軟件來彌補(bǔ)!我們先把時鐘點亮,讓他走上幾個小時或者是幾天,看看到底誤差是多少!取個平均值。(這里比如我們10小時快1秒)那么可以通過以下語句if(hour%10=0)sec-精心整理來彌補(bǔ)!這樣可能會出現(xiàn)這樣的現(xiàn)象:秒直接跳變!我們可以再通過細(xì)分來實現(xiàn),不要10小時那么大,小些的就行!具體的操作還是留給朋友們吧!比)?這回我們來講講鍵盤,大家肯定見過銀行柜員機(jī)吧,取錢輸入密碼就要用到鍵盤,超市購物取回寄存物品要輸入密碼,還有你現(xiàn)在在用的PC機(jī)的鍵盤。但是鍵盤的是怎么工作的呢?一般有2種方式:(1)掃描法,不斷掃描鍵盤的狀態(tài),送C
50、PU判斷并處理。如果鍵盤數(shù)目一大的話,顯然不適合(2)線反轉(zhuǎn)法,通過行列狀態(tài)的改變來判斷有無鍵被按下!?現(xiàn)在我們在P1接個4*4的鍵盤,P1.0-P1.3接行,P1.4-P1.7接列,再接4個4K7的上拉電阻至VCC。代碼如下:精心整理/鍵盤掃描法程序/用數(shù)碼管顯示相應(yīng)的鍵值/P1.0P1.3接行/Pl.4Pl.7接列#includereg51.hunsignedcharcodetab=0 x3F,0 x06,0 x5B,0 x4F,?0 x66,0 x6D,0 x7D,0 x07,?0 x7F,0 x6F,0 x77,0 x7C,?0 x39,0 x5E,0 x79,0 x71;/0到F的1
51、6個鍵植/*1*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*vt*/*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T
52、*T*T*T*T*T*T*T*T*T*T*T*/voidDelayt(unsignedchart)/延時函數(shù)精心整理unsignedchari;for(t=0;i=t;t+)?for(i=0;iT*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*/bitpkey(void)/判斷鍵的否被按下,通過返回值確定Pl=0 xf0;if(Pl!=0 xf0)?Delayt(25);?if(P1!=
53、0 xf0)?return1;精心整理?else?丄?return0;?else?return“/vt*vt*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*%X*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*vt*vt*vt*vt*X*vt*vt*vt*/*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*
54、T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*T*/void/主函數(shù)unsignedcharkey,j,k,s;while(1)?if(pkey()=1)精心整理?I?P1=0 xfe;?k=0 xfe;?for(j=0;j4;j+)?l?s=P1&0 xf0;?switch(s)?case0 xe0:key=4*j+0;break;?case0 xd0:key=4*j+1;break;?case0 xb0:key=4*j+2;break;?case0 x70:key=4*j+3;break;?default:break;?精心整理?k=(k1)|0 x01;?P1=k;?/for?/if/if(Pl&0 xf0)=0 xf0)?P0=tabk
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 教學(xué)設(shè)計方案作業(yè)
- XX公司天花吊頂施工合作合同
- 個人貸款合同范文及格式
- 個人保證擔(dān)保借款合同書正式版
- 臨街門面租賃合同標(biāo)準(zhǔn)版
- 中鐵物資商城物流配送合同新范本
- 個人住房抵押借款合同模板
- 產(chǎn)品生產(chǎn)裝配標(biāo)準(zhǔn)化合同
- 采購預(yù)付款合同范本
- 臨建勞務(wù)合同范本
- 廉潔應(yīng)征承諾書
- 醫(yī)院定崗定編
- 計算機(jī)網(wǎng)絡(luò)畢業(yè)論文3000字
- 2023年大學(xué)物理化學(xué)實驗報告化學(xué)電池溫度系數(shù)的測定
- 農(nóng)村公共基礎(chǔ)知識
- 腦出血的護(hù)理課件腦出血護(hù)理查房PPT
- 煤礦機(jī)電運(yùn)輸安全培訓(xùn)課件
- 扣繳個人所得稅報告表-(Excel版)
- Unit+4+History+and+Traditions單元整體教學(xué)設(shè)計課件 高中英語人教版(2019)必修第二冊單元整體教學(xué)設(shè)計
- 2023年全國自學(xué)考試00054管理學(xué)原理試題答案
- 六年級譯林版小學(xué)英語閱讀理解訓(xùn)練經(jīng)典題目(附答案)
評論
0/150
提交評論