51單片機C語言知識編程學習基礎及其實例_第1頁
51單片機C語言知識編程學習基礎及其實例_第2頁
51單片機C語言知識編程學習基礎及其實例_第3頁
51單片機C語言知識編程學習基礎及其實例_第4頁
51單片機C語言知識編程學習基礎及其實例_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、基礎知識:51單片機編程基礎第一節(jié):單數碼管按鍵顯示第二節(jié):雙數碼管可調秒表第三節(jié):十字路口交通燈第四節(jié):數碼管驅動第五節(jié):鍵盤驅動第六節(jié):低頻頻率計第七節(jié):電子表第八節(jié):串行口應用基礎知識:51單片機編程基礎單片機的外部結構DIP40雙列直插;PO,P1,P2,P3四個8位準雙向I/O引腳;(作為I/O輸入時,要先輸出高電平)電源VCC(PIN40)和地線GND(PIN20);高電平復位RESET(PIN9);(10uF電容接VCC與RESET,即可實現上電復位)內置振蕩電路,外部只要接晶體至X1(PIN18)和X0(PIN19);(頻率為主頻的12倍)程序配置EA(PIN31)接高電平VC

2、C;(運行單片機內部ROM中的程序)P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1單片機內部I/O部件:(所為學習單片機,實際上就是編程控制以下I/O部件,完成指定任務)四個8位通用I/O端口,對應引腳P0、P1、P2和P3;兩個16位定時計數器;(TMOD,TCON,TL0,TH0,TL1,TH1)一個串行通信接口;(SCON,SBUF)一個中斷控制器;(IE,IP)針對AT89C52單片機,頭文件AT89x52.h給出了SFR特殊功能寄存器所有端口的定義。C語言編程基礎十六進制表示字節(jié)0 x5a:二進制為01011010B;0 x6E為01101110。如果將一個16位二

3、進數賦給一個8位的字節(jié)變量,則自動截斷為低8位,而丟掉高8位。+var表示對變量var先增一;var表示對變量后減一。x|=0 x0f;表示為x=x|0 x0f;TMOD=(TMOD&0 xf0)|0 x05表示給變量TMOD的低四位賦值0 x5,而不改變TMOD的高四位。While(1);表示無限執(zhí)行該語句,即死循環(huán)。語句后的分號表示空循環(huán)體,也就是;在某引腳輸出高電平的編程方法:(比如P1.3(PIN4)引腳)代碼#include該頭文檔中有單片機內部資源的符號化定義,其中包含P1.3voidmain(void)/void表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口P1_3=

4、1;/給P1_3賦值1,引腳P1.3就能輸出高電平VCCWhile(1);/死循環(huán),相當LOOP:gotoLOOP;注意:P0的每個引腳要輸出高電平時,必須外接上拉電阻(如4K7)至VCC電源。在某引腳輸出低電平的編程方法:(比如P2.7引腳)代碼#include該頭文檔中有單片機內部資源的符號化定義,其中包含P2.7voidmain(void)/void表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口P2_7=0;/給P2_7賦值0,引腳P2.7就能輸出低電平GNDWhile(1);/死循環(huán),相當LOOP:gotoLOOP;在某引腳輸出方波編程方法:(比如P3.1引腳)代碼#inc

5、lude該頭文檔中有單片機內部資源的符號化定義,其中包含P3.1voidmain(void)/void表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口While(1)/非零表示真,如果為真則執(zhí)行下面循環(huán)體的語句P3_1=1;/給P3_1賦值1,引腳P3.1就能輸出高電平VCCP3_1=0;/給P3_1賦值0,引腳P3.1就能輸出低電平GND/由于一直為真,所以不斷輸出高、低、高、低從而形成方波將某引腳的輸入電平取反后,從另一個引腳輸出:(比如P0.4=NOT(P1.1)代碼#include該頭文檔中有單片機內部資源的符號化定義,其中包含P0.4和P1.1voidmain(void)/

6、void表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口P1_1=1;/初始化。P1.1作為輸入,必須輸出高電平While(1)/非零表示真,如果為真則執(zhí)行下面循環(huán)體的語句if(P1_1=1)/讀取P1.1,就是認為P1.1為輸入,如果P1.1輸入高電平VCCP0_4=0;/給P0_4賦值0,引腳P0.4就能輸出低電平GNDelse/否則P1.1輸入為低電平GND/P0_4=0;/給P0_4賦值0,引腳P0.4就能輸出低電平GNDP0_4=1;/給P0_4賦值1,引腳P0.4就能輸出高電平VCC/由于一直為真,所以不斷根據P1.1的輸入情況,改變P0.4的輸出電平將某端口8個引腳輸入

7、電平,低四位取反后,從另一個端口8個引腳輸出:(比如P2=NOT(P3)代碼#include該頭文檔中有單片機內部資源的符號化定義,其中包含P2和P3voidmain(void)/void表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口P3=0 xff;/初始化。P3作為輸入,必須輸出高電平,同時給P3口的8個引腳輸出高電平While(1)/非零表示真,如果為真則執(zhí)行下面循環(huán)體的語句6.6./取反的方法是異或1,而不取反的方法則是異或0P2=P30 x0f/讀取P3,就是認為P3為輸入,低四位異或者1,即取反,然后輸出/由于一直為真,所以不斷將P3取反輸出到P2注意:一個字節(jié)的8位D

8、7、D6至DO,分別輸出到P3.7、P3.6至P3.0,比如P3=0 x0f,則P3.7、P3.6、P3.5、P3.4四個引腳都輸出低電平,而P3.3、P3.2、P3.1、P3.0四個引腳都輸出高電平。同樣,輸入一個端口P2,即是將P2.7、P2.6至P2.0,讀入到一個字節(jié)的8位D7、D6至DO。共9頁:上一頁123456789下一頁第一節(jié):單數碼管按鍵顯示單片機最小系統的硬件原理接線圖:接電源:VCC(PIN40)、GND(PIN20)。加接退耦電容O.luF接晶體:X1(PIN18)、X2(PIN19)。注意標出晶體頻率(選用12MHz),還有輔助電容30pF接復位:RES(PIN9)。

9、接上電復位電路,以及手動復位電路,分析復位工作原理接配置:EA(PIN31)。說明原因。發(fā)光二極的控制:單片機I/O輸出將一發(fā)光二極管LED的正極邙日極)接P1.1,LED的負極(陰極)接地GND。只要P1.1輸出高電平VCC,LED就正向導通(導通時LED上的壓降大于1V),有電流流過LED,至發(fā)LED發(fā)亮。實際上由于P1.1高電平輸出電阻為10K,起到輸出限流的作用,所以流過LED的電流小于(5V-1V)/10K=0.4mA。只要P1.1輸出低電平GND,實際小于0.3V,LED就不能導通,結果LED不亮。開關雙鍵的輸入:輸入先輸出高一個按鍵KEY_ON接在P1.6與GND之間,另一個按鍵

10、KEY_OFF接P1.7與GND之間,按KEY_ON后LED亮,按KEY_OFF后LED滅。同時按下LED半亮,LED保持后松開鍵的狀態(tài),即ON亮OFF滅。代碼#include#defineLEDPIT/用符號LED代替P1_1#defineKEY_ONP1A6/用符號KEY_ON代替P1_6#defineKEY_OFFP1A7/用符號KEY_OFF代替P1_7voidmain(void)/單片機復位后的執(zhí)行入口,void表示空,無輸入參數,無返回值KEY_ON=1;/作為輸入,首先輸出高,接下KEY_ON,P1.6則接地為0,否則輸入為1KEY_OFF=1;/作為輸入,首先輸出高,接下KEY

11、_OFF,P1.7則接地為0否則輸入為1While(1)/永遠為真,所以永遠循環(huán)執(zhí)行如下括號內所有語句if(KEY_ON=0)LED=1;/是KEY_ON接下,所示P1.1輸出高,LED亮if(KEY_OFF=0)LED=0;/是KEY_OFF接下,所示P1.1輸出低,LED滅/松開鍵后,都不給LED賦值,所以LED保持最后按鍵狀態(tài)。/同時按下時,LED不斷亮滅,各占一半時間,交替頻率很快,由于人眼慣性,看上去為半亮態(tài)數碼管的接法和驅動原理一支七段數碼管實際由8個發(fā)光二極管構成,其中7個組形構成數字8的七段筆畫,所以稱為七段數碼管,而余下的1個發(fā)光二極管作為小數點。作為習慣,分別給8個發(fā)光二極

12、管標上記號:a,b,c,d,e,f,g,h。對應8的頂上一畫,按順時針方向排,中間一畫為g,小數點為ho我們通常又將各二極與一個字節(jié)的8位對應,a(D0),b(D1),c(D2),d(D3),e(D4),f(D5),g(D6),h(D7),相應8個發(fā)光二極管正好與單片機一個端口Pn的8個引腳連接,這樣單片機就可以通過引腳輸出高低電平控制8個發(fā)光二極的亮與滅,從而顯示各種數字和符號;對應字節(jié),引腳接法為:a(Pn.O),b(Pn.1),c(Pn.2),d(Pn.3),e(Pn.4),f(Pn.5),g(Pn.6),h(Pn.7)。如果將8個發(fā)光二極管的負極(陰極)內接在一起,作為數碼管的一個引腳

13、,這種數碼管則被稱為共陰數碼管,共同的引腳則稱為共陰極,8個正極則為段極。否則,如果是將正極邙日極)內接在一起引出的,則稱為共陽數碼管,共同的引腳則稱為共陽極,8個負極則為段極。以單支共陰數碼管為例,可將段極接到某端口Pn,共陰極接GND,則可編寫出對應十六進制碼的七段碼表字節(jié)數據如右圖:顯示字符共陰扱段選碼女陽根段選碼顯示宇裔共陰極段選諂共陽極段選碼03FHCOHC39HCH106HF9HD5EHA1H2;;5EHA4HE.79H.選H34FHBOHF71HS4H466H99HP73H82H6DH92HU3EH豳H67DH伽r?31H:CEH707HFSHy6EH91H8-7FHSOHFBH

14、OOHg6FH90HOOHFFHA77HSSHB7CH83H16鍵碼顯示的程序我們在P1端口接一支共陰數碼管SLED,在P2、P3端口接16個按鍵,分別編號為KEY_O、KEY_1到KEY_F,操作時只能按一個鍵,按鍵后SLED顯示對應鍵編號。代碼#include#defineSLEDP1#defineKEY_0P2A0#defineKEY_1卩2人1#defineKEY_2卩2八2#defineKEY_3卩2人3#defineKEY_4卩2八4#defineKEY_5卩2人5#defineKEY_6卩2八6#defineKEY_7卩2人7#defineKEY_8P3A0#defineKEY_

15、9卩3人1#defineKEY_A卩3八2#defineKEY_B卩3人3#defineKEY_C卩3八4#defineKEY_D卩3人5#defineKEY_E卩3八6#defineKEYFP3A719.Codeunsigned19.CodeunsignedcharSeg7Code16=/用十六進數作為數組下標,可直接取得對應的七段編碼字節(jié)20./21.0 x3f,0 x06,0 x5b,21.0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x70 x7c,0 x39,0 x5e,0 x79,0 x71;22.voi

16、dmain(void)23.24.25.unsignedchari=0;/作為數組下標24.25.P2=0 xff;/P2作為輸入,初始化輸出高26.P3=0 xff;/P3作為輸入,初始化輸出高26.P3=0 xff;/P3作為輸入,初始化輸出高27.While(1)i=0 xB;28.i=0 xB;35.if(KEYCi=0 xC;if(KEYDi=0 xD;36.if(KEYEi=0 xE;if(KEYF35.if(KEYCi=0 xC;if(KEYDi=0 xD;36.if(KEYEi=0 xE;if(KEYFi=0 xF;37.SLED=Seg7Codei;/開始時顯示0,根據i取應

17、七段編碼29.if(KEY0=0:|i=0;if(KEY1=0:1i=1;30.if(KEY2=0:ii=2;if(KEY3=0:)i=3;31.if(KEY4=0:ii=4;if(KEY5=0:)i=5;32.if(KEY6=0:ii=6;if(KEY7=0:ii=7;33.if(KEY8=0:ii=8;if(KEY9=0:)i=9;34.if(0i=0 xA;if(0)KEYAKEYB38.39.共9頁:上一頁123456789下一頁第二節(jié):雙數碼管可調秒表解:只要滿足題目要求,方法越簡單越好。由于單片機I/O資源足夠,所以雙數碼管可接成靜態(tài)顯示方式,兩個共陰數碼管分別接在P1(秒十位)和

18、P2(秒個位)口,它們的共陰極都接地,安排兩個按鍵接在P3.2(十位數調整)和P3.3(個位數調整)上,為了方便計時,選用12MHz的晶體。為了達到精確計時,選用定時器方式2,每計數250重載一次,即250us,定義一整數變量計數重載次數,這樣計數4000次即為一秒。定義兩個字節(jié)變量S10和S1分別計算秒十位和秒個位。編得如下程序:代碼1.#include2.Codeunsigned七段編碼字節(jié)charSeg7Code16=/用十六進數作為數組下標,可直接取得對應的3./0123456789AbCdEF4.0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0

19、x07,0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71;voidmain(void)unsignedintus250=0;unsignedchars10=0;unsignedcharsi=0;unsignedcharkey10=0;/記憶按鍵狀態(tài),為1按下unsignedcharkey1=0;/記憶按鍵狀態(tài),為1按下/初始化定時器Timer。TMOD=(TMOD&0 xF0)|0 x02;TH1=-250;/對于8位二進數來說,-250=6,也就是加250次1時為256,即為0TR1=1;while(1)/循環(huán)1P1=Seg7Codes10;/顯

20、示秒十位P2=Seg7Codes1;/顯示秒個位while(1)/循環(huán)2/計時處理if(TF0=1)TF0=0;if(+us250=4000)us250=0;if(+s1=10)s1=0;if(+s10=6)s10=0;break;/結束循環(huán)2”,修改顯示/按十位鍵處理P3.2=1;/P3.2作為輸入,先要輸出高電平if(keylO=1)/等松鍵if(P3.2=1)key1O=O;else/未按鍵if(P3.2=0)key1O=1;if(+s10=6)s10=0;break;/結束循環(huán)2”,修改顯示/按個位鍵處理P3.3=1;/P3.3作為輸入,先要輸出高電平if(key1=1)/等松鍵if(

21、P3.3=1)key1=0;48.else/未按鍵if(P3.3=0)key1=1;if(+s1=10)s1=0;break;/結束循環(huán)2”,修改顯示/循環(huán)2end/循環(huán)1end/mainend共9頁:上一頁1234567】8】9下一頁第三節(jié):十字路口交通燈如果一個單位時間為1秒,這里設定的十字路口交通燈按如下方式四個步驟循環(huán)工作:60個單位時間,南北紅,東西綠;10個單位時間,南北紅,東西黃;尢60個單位時間,南北綠,東西紅;尢10個單位時間,南北黃,東西紅;尢解:用P1端口的6個引腳控制交通燈,高電平燈亮,低電平燈滅。代碼#include/sbit用來定義一個符號位地址,方便編程,提高可讀

22、性,和可移植性sbitSNRed=P1入0;/南北方向紅燈sbitSNYellow=P1入1;/南北方向黃燈sbitSNGreen=P1入2;/南北方向綠燈sbitEWRed=P1入3;/東西方向紅燈sbitEWYellow=P1入4;/東西方向黃燈sbitEWGreen=P1入5;/東西方向綠燈/*用軟件產生延時一個單位時間*/voidDelay1Unit(void)unsignedinti,j;for(i=0;i1000;i+)for(j0;j1000;j+);/通過實測,調整j循環(huán)次數,產生1ms延時/還可以通過生成匯編程序來計算指令周期數,結合晶體頻率來調整j循環(huán)次數,接近1msTOC

23、 o 1-5 h z/*延時n個單位時間*/voidDelay(unsignedintn)for(;n!=0;n-)Delay1Unit();voidmain(void)while(1)SNRed=0;SNYellow=0;SNGreen=1;EWRed=1;EWYellow=0;EWGreen=0;Delay(60);SNRed=0;SNYellow=1;SNGreen=0;EWRed=1;EWYellow=0;EWGreen=0;Delay(10);SNRed=1;SNYellow=0;SNGreen=0;EWRed=0;EWYellow=0;EWGreen=1;Delay(60);SNR

24、ed=1;SNYellow=0;SNGreen=O;EWRed=O;EWYellow=1;EWGreen=O;Delay(10);共9頁:上一頁123456789下一頁第四節(jié):數碼管驅動顯示“12345678”P1端口接8聯共陰數碼管SLED8的段極:P1.7接段h,.,P1.0接段aP2端口接8聯共陰數碼管SLED8的段極:P2.7接左邊的共陰極,P2.0接右邊的共陰極方案說明:晶振頻率fosc=12MHz,數碼管米用動態(tài)刷新方式顯示,在1ms定時斷服務程序中實現代碼#includeunsignedcharDisBuf8;/全局顯示緩沖區(qū),DisBuf0對應右SLED,DisBuf7對應左S

25、LED,voidDisplayBrush(void)codeunsignedcharcathode8=0 xfe,0 xfd,0 xfb,0 xf7,0 xef,0 xdf,0 xbf,0 x7f;/陰極控制碼CodeunsignedcharSeg7Code16=/用十六進數作為數組下標,可直接取得對應的七段編碼字節(jié)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;staticunsignedchari=0;/(0i=8)i=0;/指向下一個數碼管和相應

26、數據voidTimer0IntRoute(void)interrupt1TL0TH0-1000;/由于TL0只有8bits,所以將(-1000)低8位賦給TL0TH0(-1000)8;/?。?1000)的高8位賦給TH0,重新定時1msDisplayBrush();voidTimer0Init(void)TMOD=(TMOD&OxfO)|0 x01;/初始化,定時器TO,工作方式121.TL0=-1000;/定時1ms22.TH0=(-1000)8;23.TRO=1;/允許T0開始計數24.ET0=1;/允許T0計數溢出時產生中斷請求25.26.voidDisplay(unsignedchar

27、index,unsignedchardataValue)DisBufindex=dataValue;voidmain(void)unsignedchari;for(i=0;i8;i+)Display(i,8-i);/DisBuf0為右,DisBuf7為左Timer0Init();EA=1;/允許CPU響應中斷請求While(1);共9頁:上一頁123456789下一頁第五節(jié):鍵盤驅動指提供一些函數給任務調用,獲取按鍵信息,或讀取按鍵值。定義一個頭文檔KEY.H,描述可用函數,如下:代碼#ifndef_KEY_H_/防止重復引用該文檔,如果沒有定義過符號_KEY_H_,貝Q編譯下面語句#defi

28、ne_KEY_H_只要引用過一次,即#includekey.h,則定義符號_KEY_H_unsignedcharkeyHit(void);/如果按鍵,貝V返回非0,否貝V返回0unsignedcharkeyGet(void);/讀取按鍵值,如果沒有按鍵則等待到按鍵為止voidkeyPut(unsignedcharucKeyVal);/保存按鍵值ucKeyVal至U按鍵緩沖隊列末voidkeyBack(unsignedcharucKeyVal);/退回鍵值ucKeyVal至U按鍵緩沖隊列首#endif定義函數體文檔KEY.C,如下:代碼#include“key.h#defineKeyBufSiz

29、e16定義按鍵緩沖隊列字節(jié)數unsignedcharKeyBufKeyBufSize;/定義一個無符號字符數組作為按鍵緩沖隊列。該隊列為先進/先出,循環(huán)存取,下標從0到KeyBufSize-1unsignedcharKeyBufWp=O;/作為數組下標變量,記錄存入位置unsignedcharKeyBufRp=O;/作為數組下標變量,記錄讀出位置/如果存入位置與讀出位置相同,則表明隊列中無按鍵數據unsignedcharkeyHit(void)if(KeyBufWp=KeyBufRp)return(0);elsereturn(1);10.unsignedcharkeyGet(void)unsi

30、gnedcharretVal;/暫存讀出鍵值while(keyHit()=0);/等待按鍵,因為函數keyHit()的返回值為0表示無按鍵retVal=KeyBufKeyBufRp;/從數組中讀出鍵值if(+KeyBufRp=KeyBufSize)KeyBufRp=0;/讀位置加1,超出隊列貝V循環(huán)回初始位置return(retVal);18.voidkeyPut(unsignedcharucKeyVal)KeyBufKeyBufWp=ucKeyVal;/鍵值存入數組if(+KeyBufWp=KeyBufSize)KeyBufWp=0;/存入位置加1,超出隊列貝V循環(huán)回初始位置23./*23.

31、/*由于某種原因,讀出的按鍵,沒有用,但其它任務要用該按鍵,但傳送又不方便。此時可以退回按鍵隊列。就如取錯了信件,有必要退回一樣Q*26.voidkeyBack(unsignedcharucKeyVal)/*如果KeyBufRp=O;減1后則為FFH,大于KeyBufSize,即從數組頭退回到數組尾?;蛘哂捎诟蓴_使得KeyBufRp超出隊列位置,也要調整回到正常位置,*/if(-KeyBufRp=KeyBufSize)KeyBufRp=KeyBufSize-1;KeyBufKeyBufRp=ucKeyVal;/回存鍵值下面漸進講解鍵盤物理層的驅動。電路共同點:P2端口接一共陰數碼管,共陰極接G

32、ND,P2.0接a段、P2.1接b段、P2.7接h段。軟件共同點:codeunsignedcharSeg7Code10是七段數碼管共陰編碼表。CodeunsignedcharSeg7Code16=/0123456789AbCdEF0 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;例一:P1.0接一按鍵到GND,鍵編號為6,顯示按鍵。代碼#include#include“KEY.H”voidmain(void)P1_0=1;/作為輸入引腳,必須先輸出高電平

33、while(1)/永遠為真,即死循環(huán)if(P1_0=0)/如果按鍵,則為低電平keyPut(6);/保存按鍵編號值為按鍵隊列while(P1_0=0);/如果一直按著鍵,則不停地執(zhí)行該循環(huán),實際是等待松鍵if(keyHit()!=0)/如果隊列中有按鍵P2=Seg7CodekeyGet();/從隊列中取出按鍵值,并顯示在數碼管上例二:在例一中考慮按鍵20ms抖動問題。代碼#include#include“KEY.H”voidmain(void)P1_0=1;/作為輸入引腳,必須先輸出高電平while(1)/永遠為真,即死循環(huán)if(P1_0=0)/如果按鍵,則為低電平delay20ms();/延

34、時20ms,跳過接下抖動keyPut(6);/保存按鍵編號值為按鍵隊列while(P1_0=0);/如果一直按著鍵,則不停地執(zhí)行該循環(huán),實際是等待松鍵delay20ms();/延時20ms,跳過松開抖動TOC o 1-5 h zif(keyHit()!=0)/如果隊列中有按鍵P2=Seg7CodekeyGet();/從隊列中取出按鍵值,并顯示在數碼管上例三:在例二中考慮干擾問題。即小于20ms的負脈沖干擾。代碼#include#include“KEY.H”voidmain(void)P1_0=1;/作為輸入引腳,必須先輸出高電平while(1)/永遠為真,即死循環(huán)if(P1_0=0)/如果按鍵

35、,則為低電平delay20ms();/延時20ms,跳過接下抖動if(P1_0=1)continue;/假按鍵keyPut(6);/保存按鍵編號值為按鍵隊列while(P1_0=0);/如果一直按著鍵,則不停地執(zhí)行該循環(huán),實際是等待松鍵delay20ms();/延時20ms,跳過松開抖動if(keyHit()!=0)/如果隊列中有按鍵P2=Seg7CodekeyGet();/從隊列中取出按鍵值,并顯示在數碼管上例四:狀態(tài)圖編程法。通過20ms周期中斷,掃描按鍵。代碼/*采用晶體為12KHz時,指令周期為1ms(即主頻為1KHz),這樣T0工作在定時器方式2,8位自動重載。計數值為20,即可產生

36、20ms的周期性中斷,在中斷服務程序中實現按鍵掃描3.*3.*#include#include“KEY.H”voidmain(void)TMOD=(TMOD&OxfO)|0 x02;/不改變T1的工作方式,TO為定時器方式2TH0=-20;/計數周期為20個主頻脈,即20msTL0=TH0;/先軟加載一次計數值TR0=1;/允許T0開始計數ET0=1;/允許T0計數溢出時產生中斷請求EA=1;/允許CPU響應中斷請求while(1)/永遠為真,即死循環(huán)if(keyHit()!=0)/如果隊列中有按鍵P2=Seg7CodekeyGet();/從隊列中取出按鍵值,并顯示在數碼管上voidtimer

37、0int(void)interrupt1/20ms;T0的中斷號為1staticunsignedcharsts=0;P1_0=1;/作為輸入引腳,必須先輸出高電平switch(sts)case0:if(P1_0=0)sts=1;break;/按鍵貝V轉入狀態(tài)1case1:if(P1_0=1)sts=0;/假按錯,或干擾,回狀態(tài)0elsests=2;keyPut(6);/確實按鍵,鍵值入隊列,并轉狀態(tài)2break;30.case2:if(P10=1)sts=3;break;/如果松鍵,貝V轉狀態(tài)331.case3:32.if(P1_0=0)sts=2;/假松鍵,回狀態(tài)233.elsests=0;

38、/真松鍵,回狀態(tài)0,等待下一次按鍵過程34.35.例五:狀態(tài)圖編程法。代碼/*2.如果采用晶體為12MHz時,指令周期為1us(即主頻為1MHz),要產生20ms左右的計時,則計數值達到20000,T0工作必須為定時器方式1,16位非自動重載,即可產生20ms的周期性中斷,在中斷服務程序中實現按鍵掃描Q*#include#include“KEY.H”voidmain(void)TMOD=(TMOD&0 xf0)|0 x01;/不改變T1的工作方式,T0為定時器方式1TL0=-20000;/計數周期為20000個主頻脈,自動取低8位TH0=(-20000)8;/右移8位,實際上是取高8位TR0=

39、1;/允許T0開始計數ET0=1;/允許T0計數溢出時產生中斷請求13.EA=1;CPU13.EA=1;CPU14.15.16.17.18.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.if(keyHit()!=0)/如果隊列中有按鍵P2=Seg7CodekeyGet();/從隊列中取出按鍵值,并顯示在數碼管上voidtimer0int(void)interrupt1/20ms;T0的中斷號為1staticunsignedcharsts=0;TL0=-20000;/方式1為軟件重載TH0=(-20000

40、)8;/右移8位,實際上是取高8位P1_0=1;/作為輸入引腳,必須先輸出高電平switch(sts)case0:if(P1_0=0)sts=1;break;/按鍵貝V轉入狀態(tài)1case1:if(P1_0=1)sts=0;/假按錯,或干擾,回狀態(tài)0elsests=2;keyPut(6);/確實按鍵,鍵值入隊列,并轉狀態(tài)2breakelsests=2;keyPut(6);/確實按鍵,鍵值入隊列,并轉狀態(tài)2break;case2:if(P10=1)sts=3;break;/如果松鍵,貝V轉狀態(tài)3case3:if(P1_0=0)sts=2;/假松鍵,回狀態(tài)2例六:4X4按鍵。代碼/*由P1端口的高4

41、位和低4位構成4X4的矩陣鍵盤,本程序只認為單鍵操作為合法,同時按多鍵時無效。這樣下面的X,Y的合法值為0 x7,0 xb,0 xd,Oxe,0 xf,通過表keyCode影射變換可得按鍵值4*/#include#include“KEY.H”unsignedcharkeyScan(void)/返回0表示無按鍵,或無效按鍵,其它值為按鍵編碼值codeunsignedcharkeyCode16=/0 x0,0 x1,0 x2,0 x3,0 x4,0 x5,0 x6,0 x7,0 x8,0 x9,0 xA,0 xB,0 xC,0 xD,0 xE,0 xF0,0,0,0,0,0,0,1,0,0,0,2

42、,0,4,0;unsignedcharx,y,retVal;P1=0 x0f;/低四位輸入,高四位輸出0 x=P1&0 x0f;/P1輸入后,清高四位,作為X值P1=0 xf0;/高四位輸入,低四位輸出0y=(P14)&0 x0f;/P1輸入后移位到低四位,并清高四位,作為Y值retVal=keyCodex*4+keyCodey;/根據本公式倒算按鍵編碼if(retVal=0)return(0);elsereturn(retVal-4);/比如按鍵1,得X=0 x7,Y=0 x7,算得retVal=5,所以返回函數值1。/雙如按鍵7,得X=0 xb,Y=0 xd,算得retVal=11,所以返

43、回函數值7。voidmain(void)TMOD=(TMOD&0 xf0)|0 x01;/不改變T1的工作方式,T0為定時器方式1TL0=-20000;/計數周期為20000個主頻脈,自動取低8位TH0=(-20000)8;/右移8位,實際上是取高8位TR0=1;/允許T0開始計數ET0=1;/允許T0計數溢出時產生中斷請求EA=1;/允許CPU響應中斷請求while(1)/永遠為真,即死循環(huán)TOC o 1-5 h zif(keyHit()!=0)/如果隊列中有按鍵P2=Seg7CodekeyGet();/從隊列中取出按鍵值,并顯示在數碼管上voidtimer0int(void)interru

44、pt1/20ms;T0的中斷號為1staticunsignedcharsts=0;TL0=-20000;/方式1為軟件重載TH0=(-20000)8;/右移8位,實際上是取高8位P1_0=1;/作為輸入引腳,必須先輸出高電平switch(sts)42.case0:if(keyScan()!=0)sts=1;break;/按鍵貝V轉入狀態(tài)143.case1:44.if(keyScan()=0)sts=0;/假按錯,或干擾,回狀態(tài)045.elsests=2;keyPut(keyScan();/確實按鍵,鍵值入隊列,并轉狀態(tài)246.break;47.case2:if(keyScan()=0)sts=

45、3;break;/如果松鍵,貝V轉狀態(tài)348.case3:49.if(keyScan()!=0)sts=2;/假松鍵,回狀態(tài)2elsests=O;/真松鍵,回狀態(tài)0,等待下一次按鍵過程共9頁:上一頁123456789下一頁第六節(jié):低頻頻率計實例目的:學時定時器、計數器、中斷應用說明:選用24MHz的晶體,主頻可達2MHz。用T1產生100us的時標,TO作信號脈沖計數器。假設晶體頻率沒有誤差,而且穩(wěn)定不變(實際上可達萬分之一);被測信號是周期性矩形波(正負脈沖寬度都不能小于0.5us),頻率小于1MHz,大于1Hz。要求測量時標1S,測量精度為0.1%。解:從測量精度要求來看,當頻率超過1KH

46、z時,可采用1S時標內計數信號脈沖個數來測量信號頻,而信號頻率低于1KHz時,可以通過測量信號的周期來求出信號頻率。兩種方法自動轉換。對于低于1KHz的信號,信號周期最小為1ms,也就是說超過1000us,而我們用的定時器計時脈沖周期為0.5us,如果定時多計或少計一個脈沖,誤差為1us,所以相對誤差為1us/1000us=0.1%。信號周期越大,即信號頻率越低,相對誤差就越小。從上面描述來看,當信號頻率超過1KHz后,信號周期就少于1000us,顯然采用上面的測量方法,不能達到測量精度要求,這時我們采用1S單位時間計數信號的脈沖個數,最少能計到1000個脈沖,由于信號頻率不超過1MHz,而我們定時脈沖為2MHz,最差多計或少計一個信號脈沖,這樣相對誤差為1/1000,可見信號頻率越高,相對誤差越小。信號除輸入到T1(P3.5)夕卜,還輸入到INT1(P3.3)。代碼unsignedintus100;/對100us時間間隔單位計數,即有多少個100us。unsignedcharS

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論