實(shí)用的51單片機(jī)C語(yǔ)言編程實(shí)例綜述_第1頁(yè)
實(shí)用的51單片機(jī)C語(yǔ)言編程實(shí)例綜述_第2頁(yè)
實(shí)用的51單片機(jī)C語(yǔ)言編程實(shí)例綜述_第3頁(yè)
實(shí)用的51單片機(jī)C語(yǔ)言編程實(shí)例綜述_第4頁(yè)
實(shí)用的51單片機(jī)C語(yǔ)言編程實(shí)例綜述_第5頁(yè)
已閱讀5頁(yè),還剩48頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、 電子發(fā)燒友 電子技術(shù)論壇基礎(chǔ)知識(shí):51單片機(jī)編程基礎(chǔ)(實(shí)用版)單片機(jī)的外部結(jié)構(gòu):1. DIP40雙列直插;2. P0,P1,P2,P3四個(gè)8位準(zhǔn)雙向I/O引腳;(作為I/O 輸入時(shí),要先輸出高電平)3. 電源 VCC(PIN40 )和地線 GND( PIN20);4. 高電平復(fù)位RESET( PIN9);( 10uF電容接VCC與RESET,即可實(shí)現(xiàn)上電復(fù)位)5. 內(nèi)置振蕩電路,外部只要接晶體至 X1 (PIN18 )和X0(PIN19 );(頻率為主頻的12倍)6. 程序配置EA(PIN31 )接高電平VCC;(運(yùn)行單片機(jī)內(nèi)部 ROM中的程序)7. P3 支持第二功能:RXD、TXD、IN

2、TO、INT1、TO、T1單片機(jī)內(nèi)部I/O部件:(所為學(xué)習(xí)單片機(jī),實(shí)際上就是編程控制以下I/O部件,完成指定任務(wù))1. 四個(gè)8位通用I/O 端口,對(duì)應(yīng)引腳P0、P1、P2和P3 ;2. 兩個(gè) 16 位定時(shí)計(jì)數(shù)器;(TMOD,TCON,TL0,TH0,TL1,TH1)3. 一個(gè)串行通信接口; ( SCON,SBUF)4. 一個(gè)中斷控制器;(IE,IP)針對(duì)AT89C52單片機(jī),頭文件AT89x52.h 給出了 SFR特殊功能寄存器所有端口的定義。C語(yǔ)言編程基礎(chǔ):1. 十六進(jìn)制表示字節(jié) 0x5a :二進(jìn)制為01011010B; 0x6E為01101110 。2. 如果將一個(gè)16位二進(jìn)數(shù)賦給一個(gè)8位

3、的字節(jié)變量,則自動(dòng)截?cái)酁榈?8位,而丟掉高8位。3. +var 表示對(duì)變量var先增一;var 表示對(duì)變量后減一。4. x |= 0x0f; 表示為 x = x | 0x0f;5. TMOD = ( TMOD & 0xf0 ) | 0x05; 表示給變量TMOD的低四位賦值0x5,而不改變TMOD的高四 位。6. While( 1 );表示無(wú)限執(zhí)行該語(yǔ)句,即死循環(huán)。語(yǔ)句后的分號(hào)表示空循環(huán)體,也就是 ;在某引腳輸出高電平的編程方法:(比如P1.3 (PIN4 )引腳)代碼1. #in elude /該頭文檔中有單片機(jī)內(nèi)部資源的符號(hào)化定義,其中包含P1.32. void mai n( void )

4、 /void表示沒(méi)有輸入?yún)?shù),也沒(méi)有函數(shù)返值,這入單片機(jī)運(yùn)行的復(fù)位入4. P1_3 = 1;/給P1_3賦值1,引腳P1.3就能輸出高電平VCC5. While( 1 );/ 死循環(huán),相當(dāng) LOOP: goto LOOP;6. 注意:P0的每個(gè)引腳要輸出高電平時(shí),必須外接上拉電阻(如 4K7 )至VCC電源。在某引腳輸出低電平的編程方法:(比如P2.7引腳)代碼1. #inelude /該頭文檔中有單片機(jī)內(nèi)部資源的符號(hào)化定義,其中包含P2.72. void main(void ) /void表示沒(méi)有輸入?yún)?shù),也沒(méi)有函數(shù)返值,這入單片機(jī)運(yùn)行的復(fù)位入口3. 4. P2_7 = 0;/給P2_7賦值

5、0,引腳P2.7就能輸出低電平 GND5. While( 1 );/ 死循環(huán),相當(dāng) LOOP: goto LOOP;6. 在某引腳輸出方波編程方法:(比如P3.1引腳)代碼1. #inelude /該頭文檔中有單片機(jī)內(nèi)部資源的符號(hào)化定義,其中包含P3.12. void main(void ) /void表示沒(méi)有輸入?yún)?shù),也沒(méi)有函數(shù)返值,這入單片機(jī)運(yùn)行的復(fù)位入口3. 4. While( 1 )/非零表示真,如果為真則執(zhí)行下面循環(huán)體的語(yǔ)句5. 6. P3_1 = 1;/給P3_1賦值1,引腳P3.1就能輸出高電平 VCC7. P3_1 = 0;/給P3_1賦值0,引腳P3.1就能輸出低電平 GND

6、8. /由于一直為真,所以不斷輸出高、低、高、低;從而形成方波9. 將某引腳的輸入電平取反后,從另一個(gè)引腳輸出:(比如P0.4 = NOT( P1.1) 代碼1. #inelude /該頭文檔中有單片機(jī)內(nèi)部資源的符號(hào)化定義,其中包含P0.4和P1.12. void main(void ) /void表示沒(méi)有輸入?yún)?shù),也沒(méi)有函數(shù)返值,這入單片機(jī)運(yùn)行的復(fù)位入口3. 4. P1_1 = 1;/初始化。P1.1作為輸入,必須輸出高電平5. While( 1 )/非零表示真,如果為真則執(zhí)行下面循環(huán)體的語(yǔ)句6. 7. if ( P1_1 = 1 )/讀取P1.1,就是認(rèn)為P1.1為輸入,如果P1.1輸入高

7、電平 VCC8. P0_4 = 0; /給P0_4賦值0,弓I腳P0.4就能輸出低電平 GND9.10.else/ P0_4/否則P1.1輸入為低電平GND=0; /給P0_4賦值0,引腳P0.4就能輸出低電平GND11. P0_4 =1; /給P0_4賦值1,引腳P0.4就能輸出高電平VCC12. /由于-直為真,所以不斷根據(jù) P1.1的輸入情況,改變P0.4的輸出電平13.將某端口 8個(gè)引腳輸入電平,低四位取反后,從另一個(gè)端口8個(gè)引腳輸出:(比如P2 = NOT( P3 )代碼1. #inelude /該頭文檔中有單片機(jī)內(nèi)部資源的符號(hào)化定義,其中包含P2和P32. void main(vo

8、id ) /void表示沒(méi)有輸入?yún)?shù),也沒(méi)有函數(shù)返值,這入單片機(jī)運(yùn)行的復(fù)位入口3. 4. P3 = 0xff;/初始化。P3作為輸入,必須輸出高電平,同時(shí)給P3 口的8個(gè)引腳輸出高電平5. While( 1 )/非零表示真,如果為真則執(zhí)行下面循環(huán)體的語(yǔ)句6. /取反的方法是異或1,而不取反的方法則是異或 07. P2 = P3A0x0f/讀取P3,就是認(rèn)為P3為輸入,低四位異或者1,即取反,然后輸出8. /由于一直為真,所以不斷將P3取反輸出到P29. 注意:一個(gè)字節(jié)的8位D7、D6至D0 ,分別輸出到P3.7、P3.6至P3.0 ,比如P3=0x0f ,則P3.7、P3.6、P3.5、P3.

9、4四個(gè)引腳都輸出低電平,而 P3.3、P3.2、P3.1、P3.0四個(gè)引腳都輸出高電平。同樣,輸入一個(gè)端口 P2 ,即是將P2.7、P2.6至P2.0,讀入到一個(gè)字節(jié)的 8位D7、D6至D0。 電子發(fā)燒友 電子技術(shù)論壇第一節(jié):?jiǎn)螖?shù)碼管按鍵顯示單片機(jī)最小系統(tǒng)的硬件原理接線圖:1. 接電源:VCC(PIN40 )、GND(PIN20 )。加接退耦電容 0.1uF2. 接晶體:X1(PIN18 )、X2( PIN19 )。注意標(biāo)出晶體頻率(選用 12MHz ),還有輔助電容30pF3. 接復(fù)位:RES( PIN9 )。接上電復(fù)位電路,以及手動(dòng)復(fù)位電路,分析復(fù)位工作原理4. 接配置:EA(PIN31

10、)。說(shuō)明原因。發(fā)光二極的控制:?jiǎn)纹瑱C(jī)I/O輸出將一發(fā)光二極管LED的正極 邙日極)接P1.1,LED的負(fù)極(陰極)接地GND。只要P1.1輸出高電平VCC, LED就正向?qū)ǎ▽?dǎo)通時(shí)LED上的壓降大于1V),有電流流過(guò)LED,至發(fā)LED發(fā)亮。實(shí)際上由于P1.1高 電平輸出電阻為10K,起到輸出限流的作用,所以流過(guò) LED的電流小于(5V-1V ) /10K = 0.4mA 。只要 P1.1輸出低電平GND,實(shí)際小于0.3V,LED就不能導(dǎo)通,結(jié)果LED不亮。開(kāi)關(guān)雙鍵的輸入:輸入先輸出高一個(gè)按鍵 KEY_ON 接在P1.6與GND之間,另一個(gè)按鍵 KEY_OFF接P1.7與GND之間,按KEY_

11、ON 后LED亮,按KEY_OFF后LED滅。同時(shí)按下LED半亮,LED保持后松開(kāi)鍵的狀態(tài),即 ON亮OFF滅。代碼1.#in elude 2.#defi ne LED P1A1 /用符號(hào)LED代替P13.#define KEY ON PM6 /用符號(hào)KEY ON代替P1 64.#define KEY OFF PM7 /用符號(hào)KEY OFF代替P1 75.void mai n( void )/單片機(jī)復(fù)位后的執(zhí)行入口, void表示空,無(wú)輸入?yún)?shù),無(wú)返回值6.7. KEY_ON = 1;/作為輸入,首先輸出高,接下 KEY_ON, P1.6則接地為0,否則輸入為18. KEY_OFF = 1;/

12、作為輸入,首先輸出高,接下KEY_OFF, P1.7則接地為0,否則輸入為19. While( 1 )/永遠(yuǎn)為真,所以永遠(yuǎn)循環(huán)執(zhí)行如下括號(hào)內(nèi)所有語(yǔ)句10. 11. if ( KEY_ON=0 ) LED=1; / 是 KEY_ON接下,所示 P1.1 輸出高,LED 亮12. if ( KEY_OFF=0 ) LED=0; / 是 KEY_OFF 接下,所示 P1.1 輸出低,LED 滅13. /松開(kāi)鍵后,都不給LED賦值,所以LED保持最后按鍵狀態(tài)。14. /同時(shí)按下時(shí),LED不斷亮滅,各占一半時(shí)間,交替頻率很快,由于人眼慣性,看上去為半亮態(tài)15. 電子發(fā)燒友 電子技術(shù)論壇數(shù)碼管的接法和驅(qū)動(dòng)

13、原理一支七段數(shù)碼管實(shí)際由8個(gè)發(fā)光二極管構(gòu)成,其中7個(gè)組形構(gòu)成數(shù)字8的七段筆畫,所以稱為七段數(shù)碼 管,而余下的1個(gè)發(fā)光二極管作為小數(shù)點(diǎn)。作為習(xí)慣,分別給 8個(gè)發(fā)光二極管標(biāo)上記號(hào):a,b,c,d,e,f,g,h 。 對(duì)應(yīng)8的頂上一畫,按順時(shí)針?lè)较蚺?,中間一畫為g,小數(shù)點(diǎn)為h。我們通常又將各二極與一個(gè)字節(jié)的8 位對(duì)應(yīng),a(D0),b(D1),c(D2),d(D3),e(D4),f(D5),g(D6),h(D7),相應(yīng)8個(gè)發(fā)光二極管正好與單片機(jī)一個(gè)端口Pn的8個(gè)引腳連接,這樣單片機(jī)就可以通過(guò)引腳輸出高低電平控制8個(gè)發(fā)光二極的亮與滅,從而顯示各種數(shù)字和符號(hào);對(duì)應(yīng)字節(jié),引腳接法為:a(Pn.O) ,b(P

14、n.1) ,c(Pn.2), d(Pn.3) ,e(Pn.4) ,f(Pn.5) ,g(Pn.6) ,h(Pn.7)。如果將8個(gè)發(fā)光二極管的負(fù)極(陰極)內(nèi)接在一起,作為數(shù)碼管的一個(gè)引腳,這種數(shù)碼管則被稱為共陰數(shù) 碼管,共同的引腳則稱為共陰極,8個(gè)正極則為段極。否則,如果是將正極邙日極)內(nèi)接在一起引出的,則 稱為共陽(yáng)數(shù)碼管,共同的引腳則稱為共陽(yáng)極,8個(gè)負(fù)極則為段極。以單支共陰數(shù)碼管為例,可將段極接到某端口Pn,共陰極接GND,則可編寫出對(duì)應(yīng)十六進(jìn)制碼的七段碼表字節(jié)數(shù)據(jù)如右圖:顯示宇需共陰機(jī)段選碼共陽(yáng)極段選碼顯示字符共陰根段選碼共陽(yáng)極段逑碼03FHCOHC39HC6H1F9HDA1H25BHA4H

15、E79H86H34FHBOHF71H34H466H99HF73H32H56DH92HU3EHC1H67DH82Hr31HCEH707HF3Hy6EH91H87FHSOH8FFHOOH9右FH90HOOHFFHA77H8SHB7CH16鍵碼顯示的程序我們?cè)赑1端口接一支共陰數(shù)碼管 SLED,在P2、P3端口接16個(gè)按鍵,分別編號(hào)為 KEY_O、KEY_1到 KEY_F,操作時(shí)只能按一個(gè)鍵,按鍵后 SLED顯示對(duì)應(yīng)鍵編號(hào)。代碼1. #include 2. #define SLED P13. #define KEY_0 P2A04. #define KEY_1 P215. #define KEY_2

16、 P226. #define KEY_3 P237. #define KEY_4 P2A48. #define KEY_5 P259. #define KEY_6 P2610. #define KEY_7 P2711. #define KEY_8 P3A012. #define KEY_9 P3113. #define KEY_A P3214. #define KEY_B P3315. #define KEY_C P3416. #define KEY_D P3517. #define KEY_E P36可直接取得對(duì)應(yīng)的七段編18. #define KEY_F P3719. Code unsig

17、nedchar Seg7Code16= / 用十六進(jìn)數(shù)作為數(shù)組下標(biāo),碼字節(jié)20. / 0123456789 A b Cd E F21. 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71;22.voidmain(void )23.24.un sig ned(:har i=0;/作為數(shù)組下標(biāo)25.P2 =0xff;P2作為輸入,初始化輸出高26.P3=0xff;P3作為輸入,初始化輸出高27.While( 1 )28.29.if(KEY_0=0 ) i=0;i

18、f(KEY_1 =0 ) i=1;30.if(KEY_2=0 ) i=2;if(KEY_3 =0 ) i=3;31.if(KEY_4=0 ) i=4;if(KEY_5 =0 ) i=5;32.if(KEY_6=0 ) i=6;if(KEY_7 =0 ) i=7;33.if(KEY_8=0 ) i=8;if(KEY_9 =0 ) i=9;34.if(KEY_A=0 ) i=0xA;if ( KEY_B=0 ) i=0xB;35.if(KEY_C=0 ) i=0xC;if ( KEY_D=0 ) i=0xD;36. if ( KEY_E = 0 ) i=0xE;if ( KEY_F = 0 ) i

19、=0xF;37. SLED = Seg7Code i ;/開(kāi)始時(shí)顯示0,根據(jù)i取應(yīng)七段編碼38. 39. 第二節(jié):雙數(shù)碼管可調(diào)秒表解:只要滿足題目要求,方法越簡(jiǎn)單越好。由于單片機(jī)I/O資源足夠,所以雙數(shù)碼管可接成靜態(tài)顯示方式,兩個(gè)共陰數(shù)碼管分別接在 P1 (秒十位)和P2 (秒個(gè)位)口,它們的共陰極都接地,安排兩個(gè)按鍵接在P3.2(十位數(shù)調(diào)整)和P3.3 (個(gè)位數(shù)調(diào)整)上,為了方便計(jì)時(shí),選用 12MHz的晶體。為了達(dá)到精確計(jì)時(shí),選用 定時(shí)器方式2,每計(jì)數(shù)250重載一次,即250us,定義一整數(shù)變量計(jì)數(shù)重載次數(shù),這樣計(jì)數(shù)4000次即為一秒。定義兩個(gè)字節(jié)變量 S10和S1分別計(jì)算秒十位和秒個(gè)位。編

20、得如下程序: 代碼1. #include 2. Code unsignedchar Seg7Code16= /用十六進(jìn)數(shù)作為數(shù)組下標(biāo),可直接取得對(duì)應(yīng)的七段編碼字節(jié)3. / 0123456789 A b Cd E F4. 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71;5.void mai n(void)6.7.un sig nedint us250 = 0;8.un sig nedchars10 = 0;9.un sig nedchars1 = 0;10

21、.un sig nedcharkey10 = 0;/記憶按鍵狀態(tài),為1按下11.un sig nedcharkey1 = 0;/記憶按鍵狀態(tài),為1按下12. /初始化定時(shí)器Timer。13. TMOD = (TMOD & 0xF0) | 0x02;14. TH1 = -250;/對(duì)于8位二進(jìn)數(shù)來(lái)說(shuō),-250=6,也就是加250次1時(shí)為256,即為015. TR1 = 1;/顯示秒十位16. while (1)/ 循環(huán) 117. P1 = Seg7Code s10 ;18.P2 = Seg7Code s1 ;/顯示秒個(gè)位19.while ( 1 )/ 循環(huán)220./計(jì)時(shí)處理21.i f ( TF

22、O = 1 )22.TFO = 0;23.if ( +us250 = 4000 )24.us250 = 0;25.if ( +s1 = 10 )26.s1 = 0;27.if ( +s10 = 6 ) s10 = 0;28.29.break ; /結(jié)束循環(huán)2,修改顯示30.31.32./按十位鍵處理33.P3.2 = 1;/P3.2作為輸入,先要輸出高電平34.if ( key10 = 1 )/等松鍵35.if ( P3.2 = 1 ) key10=0;36.37.else /未按鍵38.if ( P3.2 = 0 )39.key10 = 1;40.if ( +s10 = 6 ) s10 =

23、0;41.break ; /結(jié)束循環(huán)2,修改顯示42.43.44./按個(gè)位鍵處理45.P3.3 = 1;/P3.3作為輸入,先要輸出高電平46.if ( key1 = 1 )/等松鍵47. if ( P3.3 = 1 ) key仁0; 48.else /未按鍵49.if ( P3.3 = 0 ) key1 =1;50.if ( +s1 = 10 ) s1 = 0; 電子發(fā)燒友 電子技術(shù)論壇51. break ; II結(jié)束循環(huán)2”,修改顯示52. 53. 54. II 循環(huán) 2 end55. II 循環(huán) 1 end56. IImain end第三節(jié):十字路口交通燈如果一個(gè)單位時(shí)間為1秒,這里設(shè)定

24、的十字路口交通燈按如下方式四個(gè)步驟循環(huán)工作:60個(gè)單位時(shí)間,南北紅,東西綠;10個(gè)單位時(shí)間,南北紅,東西黃;60個(gè)單位時(shí)間,南北綠,東西紅;10個(gè)單位時(shí)間,南北黃,東西紅;解:用P1端口的6個(gè)引腳控制交通燈,高電平燈亮,低電平燈滅。代碼1. #include 2. IIsbit 用來(lái)定義一個(gè)符號(hào)位地址,方便編程,提高可讀性,和可移植性3. sbit SNRed =P1A0;II 南北方向紅燈4. sbit SNYellow 二PM1;II 南北方向黃燈5. sbit SNGreen 二PM2;II 南北方向綠燈6. sbit EWRed二PM3;II東西方向紅燈7. sbit EWYellow

25、 二PM4;II 東西方向黃燈8. sbit EWGreen 二PM5;II 東西方向綠燈9. I*用軟件產(chǎn)生延時(shí)一個(gè)單位時(shí)間 *I10. void Delay1Unit(void )11. 12. un sig ned int i, j;13. for ( i=0; i1000; i+ )14. for ( j0; j1000; j+ );II通過(guò)實(shí)測(cè),調(diào)整j循環(huán)次數(shù),產(chǎn)生1ms延時(shí)15. II還可以通過(guò)生成匯編程序來(lái)計(jì)算指令周期數(shù),結(jié)合晶體頻率來(lái)調(diào)整j循環(huán)次數(shù),接近1ms16. 17. I*延時(shí)n個(gè)單位時(shí)間*I18. void Delay( unsignedint n ) for ( ;

26、n!=0; n-) Delay1Unit(); 電子發(fā)燒友 電子技術(shù)論壇19. void main( void )20. 21. while ( 1 )22. 23. SNRed=O; SNY ellow=0; SNGree n=1; EWRed=1; EWYellow=0; EWGree n=0; Delay(60 );24. SNRed=0; SNY ellow=1; SNGree n=0; EWRed=1; EWYellow=0; EWGree n=0; Delay(10 );25. SNRed=1; SNY ellow=0; SNGree n=0; EWRed=0; EWYellow=

27、0; EWGree n=1; Delay(60 );26. SNRed=1; SNY ellow=0; SNGree n=0; EWRed=0; EWYellow=1; EWGree n=0; Delay(10 );27. 28. 第四節(jié):數(shù)碼管驅(qū)動(dòng)顯示 “ 12345678P1端口接8聯(lián)共陰數(shù)碼管SLED8的段極:P1.7接段h,,P1.0接段aP2端口接8聯(lián)共陰數(shù)碼管SLED8的段極:P2.7接左邊的共陰極,P2.0接右邊的共陰極方案說(shuō)明:晶振頻率fosc=12MHz ,數(shù)碼管采用動(dòng)態(tài)刷新方式顯示,在1ms定時(shí)斷服務(wù)程序中實(shí)現(xiàn)代碼1. #include 2. unsignedchar Di

28、sBuf8;/ 全局顯示緩沖區(qū),DisBufO對(duì)應(yīng)右 SLED, DisBuf7對(duì)應(yīng)左 SLED,3. void DisplayBrush( void )4. code unsignedchar cathode8=0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f;/陰極控制碼5. Code unsignedchar Seg7Code16= /用十六進(jìn)數(shù)作為數(shù)組下標(biāo),可直接取得對(duì)應(yīng)的七段編碼字節(jié)6. 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;7. s

29、taticunsignedchar i=0;/(0i = 8 ) i=0;/指向下一個(gè)數(shù)碼管和相應(yīng)數(shù)據(jù)12.13.voidTimer0I ntRoute(void ) in terrupt 114.15.TL0=-1000; /由于TL0只有8bits ,所以將(-1000 )低8位賦給TL016.TH0=(-1000)8;/取(-1000 )的高8位賦給TH0,重新定時(shí)1ms17.DisplayBrush();18.19.voidTimer0I nit(void )20. TMOD=(TMOD & 0xf0) | 0x01;/初始化,定時(shí)器 T0,工作方式121.TL0=-1000 ; /定

30、時(shí)1ms22.TH0=(-1000)8;23.TR0=1;/允許T0開(kāi)始計(jì)數(shù)24.ET0=1;/允許T0計(jì)數(shù)溢出時(shí)產(chǎn)生中斷請(qǐng)求25.8.P2 = Oxff;/顯示消隱,以免下一段碼值顯示在前一支 SLED9.P1 = Seg7Code DisBufi;/從顯示緩沖區(qū)取出原始數(shù)據(jù),查表變?yōu)槠叨未a后送出顯示26.void Display( unsignedchar index, unsignedchar dataValue ) DisBuf index = dataValue; 27.void main(void )28.29.unsigned char i;30.f or ( i=0; i8;

31、i+ ) Display(i, 8-i); DisBuf0 為右,DisBuf7為左31.TimerOI ni t();32.EA = 1;/允許CPU響應(yīng)中斷請(qǐng)求33.While(1);34.第五節(jié):鍵盤驅(qū)動(dòng)指提供一些函數(shù)給任務(wù)調(diào)用,獲取按鍵信息,或讀取按鍵值定義一個(gè)頭文檔KE Y.H,描述可用函數(shù),如下:代碼1. #ifndef _KEY_H_ /防止重復(fù)引用該文檔,如果沒(méi)有定義過(guò)符號(hào)_KEY_H_,則編譯下面語(yǔ)句2. #define _KEY_H_ /只要引用過(guò)一次,即 #include ,則定義符號(hào) _KEY_H_3. unsignedchar keyHit( void );/如果按鍵

32、,則返回非0,否則返回04. unsigned char keyGet(void );/讀取按鍵值,如果沒(méi)有按鍵則等待到按鍵為止5. void keyPut( unsignedchar ucKeyVal );/保存按鍵值ucKeyVal到按鍵緩沖隊(duì)列末6. void keyBack( unsignedchar ucKeyVal );/退回鍵值ucKeyVal到按鍵緩沖隊(duì)列首7. #endif定義函數(shù)體文檔 KEY.C,如下:代碼1. #include“key.h ”2. #define KeyBufSize 16 /定義按鍵緩沖隊(duì)列字節(jié)數(shù)3. unsignedchar KeyBuf KeyBu

33、fSize ;/定義一個(gè)無(wú)符號(hào)字符數(shù)組作為按鍵緩沖隊(duì)列。該隊(duì)列為先進(jìn)4. /先出,循環(huán)存取,下標(biāo)從0到 KeyBufSize-15. unsignedchar KeyBufWp=0;/作為數(shù)組下標(biāo)變量,記錄存入位置6. unsignedchar KeyBufRp=O;/作為數(shù)組下標(biāo)變量,記錄讀出位置7. /如果存入位置與讀出位置相同,則表明隊(duì)列中無(wú)按鍵數(shù)據(jù)8. unsignedchar keyHit( void )9. if ( KeyBufWp = KeyBufRp )return ( 0 ); elsereturn ( 1 ); 10.10. unsignedchar keyGet( vo

34、id )11. unsigned char retVal; / 暫存讀出鍵值12. while ( keyHit()=0 );/等待按鍵,因?yàn)楹瘮?shù)keyHit() 的返回值為0 表示無(wú)按鍵13. r etVal = KeyBuf KeyBufRp ;/ 從數(shù)組中讀出鍵值14. i f ( +KeyBufRp = KeyBufSize ) KeyBufRp=0;/讀位置加1,超出隊(duì)列則循環(huán)回初始位置15. retur n ( retVal );16. 18.char ucKeyVal )17. void keyPut( unsigned18. KeyBuf KeyBufWp = ucKeyVal

35、;/ 鍵值存入數(shù)組19. if ( +KeyBufWp = KeyBufSize ) KeyBufWp=0;/ 存入位置加1,超出隊(duì)列則循環(huán)回初始位置22.23./ *24. 由于某種原因,讀出的按鍵,沒(méi)有用,但其它任務(wù)要用該按鍵,但傳送又不方便。此時(shí)可以退回按鍵 隊(duì)列。就如取錯(cuò)了信件,有必要退回一樣25. * */26. void keyBack( unsignedchar ucKeyVal )27. 28. /*29. 如果KeyBufRp=O; 減1后則為FFH,大于KeyBufSize,即從數(shù)組頭退回到數(shù)組尾?;蛘哂捎诟蓴_使得KeyBufRp超出隊(duì)列位置,也要調(diào)整回到正常位置,30.

36、*/31. if ( -KeyBufRp = KeyBufSize ) KeyBufRp二KeyBufSize-1;32. KeyBuf KeyBufRp = ucKeyVal;/ 回存鍵值33. 下面漸進(jìn)講解鍵盤物理層的驅(qū)動(dòng)。電路共同點(diǎn):P2端口接一共陰數(shù)碼管,共陰極接 GND , P2.0接a段、P2.1接b段、P2.7接h段軟件共同點(diǎn):code un sig ned char Seg7Code10是七段數(shù)碼管共陰編碼表。Code un sig ned char Seg7Code16=/ 0123456789 A b C d E F0x3f, 0x06, 0x5b, 0x4f, 0x66,

37、 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79,0x71;例一:P1.0接一按鍵到GND,鍵編號(hào)為6 顯示按鍵。代碼1. #include 電子發(fā)燒友 電子技術(shù)論壇2. #nclude “KEY.h”3. void main( void )4. P1_0 = 1;/作為輸入引腳,必須先輸出高電平5. while ( 1 )/永遠(yuǎn)為真,即死循環(huán)6. if ( P1_0 = 0 )/如果按鍵,則為低電平7. keyPut( 6 );/保存按鍵編號(hào)值為按鍵隊(duì)列8. while ( P1_0 = 0 );/如果一直按著鍵,則不停地

38、執(zhí)行該循環(huán),實(shí)際是等待松鍵9. 10. if( keyHit() != 0 )/如果隊(duì)列中有按鍵11. P2二Seg7Code keyGet() ;/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上12. 13. 例二:在例一中考慮按鍵20ms抖動(dòng)問(wèn)題 代碼1. #include 2. #include “KEY.h”3. void main( void )4. P1_0 = 1;/作為輸入引腳,必須先輸出高電平5. while ( 1 )/永遠(yuǎn)為真,即死循環(huán)6. if ( P1_0 = 0 )/如果按鍵,則為低電平7. delay20ms(); /延時(shí)20ms,跳過(guò)接下抖動(dòng)8. keyPut( 6 );

39、/保存按鍵編號(hào)值為按鍵隊(duì)列9.while ( P1_0=0 );/如果 直按著鍵,則不停地執(zhí)行該循環(huán),實(shí)際是等待松鍵10.delay20ms();/延時(shí)20ms,跳過(guò)松開(kāi)抖動(dòng)11.12.i f ( keyHit() !=0 )/如果隊(duì)列中有按鍵13.P2=Seg7Code keyGet();/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上14.15. 電子發(fā)燒友 電子技術(shù)論壇例三:在例二中考慮干擾問(wèn)題。即小于 20ms的負(fù)脈沖干擾代碼1. #include 2. #include “KEY.h”3. void main( void )4. P1_0 = 1;/作為輸入引腳,必須先輸出高電平5. whil

40、e ( 1 )/永遠(yuǎn)為真,即死循環(huán)6. if ( P1_0 = 0 )/如果按鍵,則為低電平7. delay20ms(); /延時(shí)20ms,跳過(guò)接下抖動(dòng)8. if ( P1_0 = 1 )continue; / 假按鍵9. keyPut( 6 );/保存按鍵編號(hào)值為按鍵隊(duì)列10. while ( P1_0 = 0 );/如果一直按著鍵,則不停地執(zhí)行該循環(huán),實(shí)際是等待松鍵11. delay20ms(); /延時(shí)20ms,跳過(guò)松開(kāi)抖動(dòng)12. 13. if( keyHit() != 0 )/如果隊(duì)列中有按鍵14. P2=Seg7Code keyGet() ;/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上15

41、. 16. 例四:狀態(tài)圖編程法。通過(guò) 20ms周期中斷,掃描按鍵。代碼1. /*2.采用晶體為12KHz時(shí),指令周期為1ms (即主頻為1KHz),這樣T0工作在定時(shí)器方式2,8位自動(dòng) 重載。計(jì)數(shù)值為20,即可產(chǎn)生20ms的周期性中斷,在中斷服務(wù)程序中實(shí)現(xiàn)按鍵掃描3*/4. #include 5. #include“KEY.h”6. void main(void ) 電子發(fā)燒友 電子技術(shù)論壇7. 8. TM0D = (TM0D & OxfO ) | 0x02;/不改變T1的工作方式,TO為定時(shí)器方式29. THO = -20;/計(jì)數(shù)周期為20個(gè)主頻脈,即20ms35. 10. TL0=TH0;

42、11. TR0=1;12. ET0=1;13. EA=1;14. while ( 1 )15. /先軟加載一次計(jì)數(shù)值/允許T0開(kāi)始計(jì)數(shù)/允許T0計(jì)數(shù)溢出時(shí)產(chǎn)生中斷請(qǐng)求/允許CPU響應(yīng)中斷請(qǐng)求/永遠(yuǎn)為真,即死循環(huán)16. i f (keyHit() != 0 )/如果隊(duì)列中有按鍵17. P2二Seg7Code keyGet() ;/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上18. 19. 20. void timer0int( void ) interrupt 1/20ms ; T0 的中斷號(hào)為 121. staticunsignedchar sts=0;22. P1_0 = 1;/作為輸入引腳,必須先

43、輸出高電平23. switch ( sts )24. 25. case 0: if ( P1_0=0 ) sts=1;break ; / 按鍵則轉(zhuǎn)入狀態(tài) 126. case 1:27. i f ( P1_0=1 ) sts=0;/假按錯(cuò),或干擾,回狀態(tài) 028. else sts=2; keyPut( 6 ); /確實(shí)按鍵,鍵值入隊(duì)列,并轉(zhuǎn)狀態(tài)229. break ;30. case 2: if ( P1_0=1 ) sts=3;break ; / 如果松鍵,則轉(zhuǎn)狀態(tài) 331. case 3:32. if ( P1_0=0 ) sts=2;/ 假松鍵,回狀態(tài) 233. else sts=0;/

44、真松鍵,回狀態(tài)0,等待下一次按鍵過(guò)程34. 例五:狀態(tài)圖編程法 代碼 電子發(fā)燒友 電子技術(shù)論壇26.29. i f ( P1_0=1 ) sts=0;/假按錯(cuò),或干擾,回狀態(tài)01. /*2.如果采用晶體為12MHz時(shí),指令周期為1us (即主頻為1MHz),要產(chǎn)生20ms左右的計(jì)時(shí),則計(jì)數(shù)值達(dá)到20000,T0工作必須為定時(shí)器方式1 ,16位非自動(dòng)重載,即可產(chǎn)生20ms的周期性中斷,在中斷服務(wù)程序中實(shí)現(xiàn)按鍵掃描3.*4.#in elude 5.#i nclude“KE Y.h”6.void mai n( void )7.8.TMOD =( TMOD & 0xf0)| 0x01;/不改變T1的工

45、作方式,T0為定時(shí)器方式19.TL0 = -20000;/計(jì)數(shù)周期為20000個(gè)主頻脈,自動(dòng)取低8位10.TH0 = (-20000)8;/右移8位,實(shí)際上是取咼11.TR0=1;/允許T0開(kāi)始計(jì)數(shù)12.ET0=1;/允許T0計(jì)數(shù)溢出時(shí)產(chǎn)生中斷請(qǐng)求13.EA=1;/允許CPU響應(yīng)中斷請(qǐng)求14.while ( 1 )/永遠(yuǎn)為真,即死循環(huán)15.16.i f ( keyHit() != 0 )/如果隊(duì)列中有按鍵17.P2二Seg7Code keyGet();/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上18.19.20.void timer0int(void ) in terrupt 1/20ms ;T0的

46、中斷號(hào)為121. staticunsignedchar sts=0;22.TL0 = -20000;/方式1為軟件重載23.TH0 = (-20000)8;/右移8位,實(shí)際上是取咼24.P1_0 = 1;/作為輸入引腳,必須先輸出高電平25.switch(sts )27.case0:if ( P1_0=0 ) sts=1;break ; /按鍵則轉(zhuǎn)入狀態(tài)128.case1: 電子發(fā)燒友 電子技術(shù)論壇30.else sts=2; keyPut( 6 ); /確實(shí)按鍵,鍵值入隊(duì)列,并轉(zhuǎn)狀態(tài)231.break ;32.case 2: if ( P1_0=1 ) sts=3;break ; /如果松鍵,則轉(zhuǎn)狀態(tài)333.case 3:34.if ( P1_0=0

溫馨提示

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

評(píng)論

0/150

提交評(píng)論