版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、基礎知識:51單片機編程基礎第一節(jié):單數碼管按鍵顯示第二節(jié):雙數碼管可調秒表第三節(jié):十字路口交通燈第四節(jié):數碼管驅動第五節(jié):鍵盤驅動第六節(jié):低頻頻率計第七節(jié):電子表第八節(jié):串行口應用基礎知識:51單片機編程基礎單片機的外部結構:1. DIP40雙列直插; 2. P0,P1,P2,P3四個8位準雙向I/O引腳;(作為I/O輸入時,要先輸出高電平) 3. 電源VCC(PIN40)和地線GND(PIN20); 4. 高電平復位RESET(PIN9);(10uF電容接VCC與RESET,即可實現上電復位) 5. 內置振蕩電路,外部只要接晶體至X1(PIN18)和X0(PIN19);(頻率為主頻的12倍
2、) 6. 程序配置EA(PIN31)接高電平VCC;(運行單片機內部ROM中的程序) 7. P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1 單片機內部I/O部件:(所為學習單片機,實際上就是編程控制以下I/O部件,完成指定任務)1. 四個8位通用I/O端口,對應引腳P0、P1、P2和P3; 2. 兩個16位定時計數器;(TMOD,TCON,TL0,TH0,TL1,TH1) 3. 一個串行通信接口;(SCON,SBUF) 4. 一個中斷控制器;(IE,IP) 針對AT89C52單片機,頭文件AT89x52.h給出了SFR特殊功能寄存器所有端口的定義。C語言編程基礎:1. 十六進
3、制表示字節(jié)0x5a:二進制為01011010B;0x6E為01101110。 2. 如果將一個16位二進數賦給一個8位的字節(jié)變量,則自動截斷為低8位,而丟掉高8位。 3. +var表示對變量var先增一;var表示對變量后減一。 4. x |= 0x0f;表示為 x = x | 0x0f; 5. TMOD = ( TMOD & 0xf0 ) | 0x05;表示給變量TMOD的低四位賦值0x5,而不改變TMOD的高四位。 6. While( 1 ); 表示無限執(zhí)行該語句,即死循環(huán)。語句后的分號表示空循環(huán)體,也就是; 在某引腳輸出高電平的編程方法:(比如P1.3(PIN4)引腳)代碼1.
4、#include <AT89x52.h> /該頭文檔中有單片機內部資源的符號化定義,其中包含P1.3 2. void main( void ) /void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口 3. 4. P1_3 = 1; /給P1_3賦值1,引腳P1.3就能輸出高電平VCC 5. While(
5、160;1 ); /死循環(huán),相當 LOOP: goto LOOP; 6. 注意:P0的每個引腳要輸出高電平時,必須外接上拉電阻(如4K7)至VCC電源。在某引腳輸出低電平的編程方法:(比如P2.7引腳)代碼1. #include <AT89x52.h> /該頭文檔中有單片機內部資源的符號化定義,其中包含P2.7 2. void main( void ) /void
6、;表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口 3. 4. P2_7 = 0; /給P2_7賦值0,引腳P2.7就能輸出低電平GND 5. While( 1 ); /死循環(huán),相當 LOOP: goto LOOP; 6. 在某引腳輸出方波編程方法:(比如P3.1引腳)代碼1. #include &
7、lt;AT89x52.h> /該頭文檔中有單片機內部資源的符號化定義,其中包含P3.1 2. void main( void ) /void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口 3. 4. While( 1 ) /非零表示真,如果為真則執(zhí)行下面循環(huán)體的語句 5. 6. P3_1 =
8、0;1; /給P3_1賦值1,引腳P3.1就能輸出高電平VCC 7. P3_1 = 0; /給P3_1賦值0,引腳P3.1就能輸出低電平GND 8. /由于一直為真,所以不斷輸出高、低、高、低,從而形成方波 9. 將某引腳的輸入電平取反后,從另一個引腳輸出:( 比如 P0.4 = NOT( P1.1) )代碼1. #include &l
9、t;AT89x52.h> /該頭文檔中有單片機內部資源的符號化定義,其中包含P0.4和P1.1 2. void main( void ) /void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口 3. 4. P1_1 = 1; /初始化。P1.1作為輸入,必須輸出高電平 5. While( 1 )
10、0;/非零表示真,如果為真則執(zhí)行下面循環(huán)體的語句 6. 7. if( P1_1 = 1 ) /讀取P1.1,就是認為P1.1為輸入,如果P1.1輸入高電平VCC 8. P0_4 = 0; /給P0_4賦值0,引腳P0.4就能輸出低電平GND 9. else &
11、#160;/否則P1.1輸入為低電平GND 10. / P0_4 = 0; /給P0_4賦值0,引腳P0.4就能輸出低電平GND 11. P0_4 = 1; /給P0_4賦值1,引腳P0.4就能輸出高電平VCC 12. /由于一直為真,所以不斷根據P1.1的輸入情況,改變P0.4的輸
12、出電平 13. 將某端口8個引腳輸入電平,低四位取反后,從另一個端口8個引腳輸出:( 比如 P2 = NOT( P3 ) )代碼1. #include <AT89x52.h> /該頭文檔中有單片機內部資源的符號化定義,其中包含P2和P3 2. void main( void ) /void 表示沒有輸入參數,也沒有函數返值,這入單片機運行的復位入口 3. 4.
13、P3 = 0xff; /初始化。P3作為輸入,必須輸出高電平,同時給P3口的8個引腳輸出高電平 5. While( 1 ) /非零表示真,如果為真則執(zhí)行下面循環(huán)體的語句 6. /取反的方法是異或1,而不取反的方法則是異或0 7. P2 = P30x0f /讀取P3,就是認為P3為輸入,低四位異或者1,即取反,然后輸出 8
14、. /由于一直為真,所以不斷將P3取反輸出到P2 9. 注意:一個字節(jié)的8位D7、D6至D0,分別輸出到P3.7、P3.6至P3.0,比如P3=0x0f,則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至D0。共9頁: 上一頁 1 2 3 4 5 6 7 8 9 下一頁 第一節(jié):單數碼管按鍵顯示單片機最小系統(tǒng)的硬件原理接
15、線圖: 1. 接電源:VCC(PIN40)、GND(PIN20)。加接退耦電容0.1uF 2. 接晶體:X1(PIN18)、X2(PIN19)。注意標出晶體頻率(選用12MHz),還有輔助電容30pF 3. 接復位:RES(PIN9)。接上電復位電路,以及手動復位電路,分析復位工作原理 4. 接配置:EA(PIN31)。說明原因。 發(fā)光二極的控制:單片機I/O輸出將一發(fā)光二極管LED的正極(陽極)接P1.1,LED的負極(陰極)接地GND。只要P1.1輸出高電平VCC,LED就正向導通(導通時LED上的壓降大于1V),有電流流過LED,至發(fā)LED
16、發(fā)亮。實際上由于P1.1高電平輸出電阻為10K,起到輸出限流的作用,所以流過LED的電流小于(5V-1V)/10K = 0.4mA。只要P1.1輸出低電平GND,實際小于0.3V,LED就不能導通,結果LED不亮。開關雙鍵的輸入:輸入先輸出高一個按鍵KEY_ON接在P1.6與GND之間,另一個按鍵KEY_OFF接P1.7與GND之間,按KEY_ON后LED亮,按KEY_OFF后LED滅。同時按下LED半亮,LED保持后松開鍵的狀態(tài),即ON亮OFF滅。代碼1. #include <at89x52.h> 2. #define LED
17、0; P11 /用符號LED代替P1_1 3. #define KEY_ON P16 /用符號KEY_ON代替P1_6 4. #define KEY_OFF P17 /用符號KEY_OFF代替P1_7 5. void main( void ) /單片機復位后的執(zhí)行入口,void表示空,無輸入參
18、數,無返回值 6. 7. KEY_ON = 1; /作為輸入,首先輸出高,接下KEY_ON,P1.6則接地為0,否則輸入為1 8. KEY_OFF = 1; /作為輸入,首先輸出高,接下KEY_OFF,P1.7則接地為0,否則輸入為1 9. While( 1 ) /永遠為真,所以永遠循環(huán)執(zhí)行如下括號內所有語句
19、; 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. /松開鍵后,都不給LED賦值,所以LED保持最后按鍵狀態(tài)。 14. /同時按下時,LED不斷亮滅,
20、各占一半時間,交替頻率很快,由于人眼慣性,看上去為半亮態(tài) 15. 數碼管的接法和驅動原理 一支七段數碼管實際由8個發(fā)光二極管構成,其中7個組形構成數字8的七段筆畫,所以稱為七段數碼管,而余下的1個發(fā)光二極管作為小數點。作為習慣,分別給8個發(fā)光二極管標上記號:a,b,c,d,e,f,g,h。對應8的頂上一畫,按順時針方向排,中間一畫為g,小數點為h。 我們通常又將各二極與一個字節(jié)的8位對應,a(D0),b(D1),c(D2),d(D3),e(D4),f(D5),g(D6),
21、h(D7),相應8個發(fā)光二極管正好與單片機一個端口Pn的8個引腳連接,這樣單片機就可以通過引腳輸出高低電平控制8個發(fā)光二極的亮與滅,從而顯示各種數字和符號;對應字節(jié),引腳接法為:a(Pn.0),b(Pn.1),c(Pn.2),d(Pn.3),e(Pn.4),f(Pn.5),g(Pn.6),h(Pn.7)。 如果將8個發(fā)光二極管的負極(陰極)內接在一起,作為數碼管的一個引腳,這種數碼管則被稱為共陰數碼管,共同的引腳則稱為共陰極,8個正極則為段極。否則,如果是將正極(陽極)內接在一起引出的,則稱為共陽數碼管,共同的引腳則稱為共陽極,8個負極則為段極。
22、 以單支共陰數碼管為例,可將段極接到某端口Pn,共陰極接GND,則可編寫出對應十六進制碼的七段碼表字節(jié)數據如右圖: 16鍵碼顯示的程序我們在P1端口接一支共陰數碼管SLED,在P2、P3端口接16個按鍵,分別編號為KEY_0、KEY_1到KEY_F,操作時只能按一個鍵,按鍵后SLED顯示對應鍵編號。代碼1. #include <at89x52.h> 2. #define SLED P1 3. #define KEY_0 P20
23、0; 4. #define KEY_1 P21 5. #define KEY_2 P22 6. #define KEY_3 P23 7. #define KEY_4 P24 8. #define KEY_5 P25 9. #define KEY_6 P26 10. #define KEY_7 P27 &
24、#160; 11. #define KEY_8 P30 12. #define KEY_9 P31 13. #define KEY_A P32 14. #define KEY_B P33 15. #define KEY_C P34 16. #define KEY_D P35 17. #define K
25、EY_E P36 18. #define KEY_F P37 19. Code unsigned char Seg7Code16= /用十六進數作為數組下標,可直接取得對應的七段編碼字節(jié) 20. / 0 1 2 3 4
26、160; 5 6 7 8 9 A b C d E
27、0; F 21. 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71; 22. void main( void ) 23. 24. unsign
28、ed char i=0; /作為數組下標 25. P2 = 0xff; /P2作為輸入,初始化輸出高 26. P3 = 0xff; /P3作為輸入,初始化輸出高 27. While( 1 ) 28. 29. if( KEY_0 = 0 ) i=0;
29、 if( 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 =
30、60;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; 3
31、4. 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_
32、E = 0 ) i=0xE; if( KEY_F = 0 ) i=0xF; 37. SLED = Seg7Code i /開始時顯示0,根據i取應七段編碼 38. 39. 共9頁: 上一頁 1 2 3 4 5 6 7 8 9 下一頁第二節(jié):雙數碼管可調秒表解:只要滿足題目要求,方法越簡單越好。由于單片機I/
33、O資源足夠,所以雙數碼管可接成靜態(tài)顯示方式,兩個共陰數碼管分別接在P1(秒十位)和P2(秒個位)口,它們的共陰極都接地,安排兩個按鍵接在P3.2(十位數調整)和P3.3(個位數調整)上,為了方便計時,選用12MHz的晶體。為了達到精確計時,選用定時器方式2,每計數250重載一次,即250us,定義一整數變量計數重載次數,這樣計數4000次即為一秒。定義兩個字節(jié)變量S10和S1分別計算秒十位和秒個位。編得如下程序:代碼1. #include <at89x52.h> 2. Code unsigned char Seg7C
34、ode16= /用十六進數作為數組下標,可直接取得對應的七段編碼字節(jié) 3. / 0 1 2 3 4 5 6 7 8
35、 9 A b C d E F 4. 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
36、160;0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71; 5. void main( void ) 6. 7. unsigned int us250 = 0; 8. unsigned char s10 = 0; 9. &
37、#160;unsigned char s1 = 0; 10. unsigned char key10 = 0; /記憶按鍵狀態(tài),為1按下 11. unsigned char key1 = 0; /記憶按鍵狀態(tài),為1按下 12. /初始化定時器 Timer0 13. TMOD
38、= (TMOD & 0xF0) | 0x02; 14. TH1 = -250; /對于8位二進數來說,-250=6,也就是加250次1時為256,即為0 15. TR1 = 1; 16. while(1) /-循環(huán)1 17
39、. P1 = Seg7Code s10 /顯示秒十位 18. P2 = Seg7Code s1 /顯示秒個位 19. while( 1 ) /-循環(huán)2 20. /計時處理
40、 21. if( TF0 = 1 ) 22. TF0 = 0; 23. if( +us250 >= 4000 ) 24. us250 = 0; 25. &
41、#160;if( +s1 >= 10 ) 26. s1 = 0; 27. if( +s10 >= 6 ) s10 = 0; 28. 29.
42、0; break; /結束“循環(huán)2”,修改顯示 30. 31. 32. /按十位鍵處理 33. P3.2 = 1; /P3.2作為輸入,先要輸出高電平 34. if(
43、;key10 = 1 ) /等松鍵 35. if( P3.2 = 1 ) key10=0; 36. 37. else /未按鍵 38. if( P3.2 = 0 ) 39.
44、; key10 = 1; 40. if( +s10 >= 6 ) s10 = 0; 41. break; /結束“循環(huán)2”,修改顯示 42. 43. 44.
45、 /按個位鍵處理 45. P3.3 = 1; /P3.3作為輸入,先要輸出高電平 46. if( key1 = 1 ) /等松鍵 47. if( P3.3 = 1 ) key1=0; 48. else
46、 /未按鍵 49. if( P3.3 = 0 ) key1 = 1; 50. if( +s1 >= 10 ) s1 = 0; 51. break; /結束“循環(huán)2”,修改顯示 52. &
47、#160; 53. 54. /循環(huán)2end 55. /循環(huán)1end 56. /mainend 共9頁: 上一頁 1 2 3 4 5 6 7 8 9 下一頁 第三節(jié):十字路口交通燈如果一個單位時間為1秒,這里設定的十字路口交通燈按如下方式四個步驟循環(huán)工作: 60個單位時間,南北紅,東西綠;l 10個單位時間,南北紅,東
48、西黃;l 60個單位時間,南北綠,東西紅;l 10個單位時間,南北黃,東西紅;l解:用P1端口的6個引腳控制交通燈,高電平燈亮,低電平燈滅。代碼1. #include <at89x52.h> 2. /sbit用來定義一個符號位地址,方便編程,提高可讀性,和可移植性 3. sbit SNRed =P10; /南北方向紅燈 4. sbit SNYellow =P11; /南北方向黃燈
49、 5. sbit SNGreen =P12; /南北方向綠燈 6. sbit EWRed =P13; /東西方向紅燈 7. sbit EWYellow =P14; /東西方向黃燈 8. sbit EWGreen =P15; /東西方向綠燈 9. /* 用軟件產生延時一個單位時間 */
50、 10. void Delay1Unit( void ) 11. 12. unsigned int i, j; 13. for( i=0; i<1000; i+ ) 14. for( j<0; j<1000; j+ );
51、;/通過實測,調整j循環(huán)次數,產生1ms延時 15. /還可以通過生成匯編程序來計算指令周期數,結合晶體頻率來調整j循環(huán)次數,接近1ms 16. 17. /* 延時n個單位時間 */ 18. void Delay( unsigned int n ) for( n!=0; n- ) Delay1Unit(); 19. void&
52、#160;main( void ) 20. 21. while( 1 ) 22. 23. SNRed=0; SNYellow=0; SNGreen=1; EWRed=1; EWYellow=0; EWGreen=0; Delay( 60 ); 24. SNRed=
53、0; SNYellow=1; SNGreen=0; EWRed=1; EWYellow=0; EWGreen=0; Delay( 10 ); 25. SNRed=1; SNYellow=0; SNGreen=0; EWRed=0; EWYellow=0; EWGreen=1; Delay( 60 ); 26. SNRed=1;
54、SNYellow=0; SNGreen=0; EWRed=0; EWYellow=1; EWGreen=0; Delay( 10 ); 27. 28. 共9頁: 上一頁 1 2 3 4 5 6 7 8 9 下一頁第四節(jié):數碼管驅動顯示“12345678”P1端口接8聯共陰數碼管SLED8的段極:P1.7接段h,,P1.0接段aP2端口接8聯共陰數碼管SLED8的段極:P2.7接左邊的共陰極,P2.0接右邊的共陰極方案說明:晶振頻率fo
55、sc=12MHz,數碼管采用動態(tài)刷新方式顯示,在1ms定時斷服務程序中實現代碼1. #include <at89x92.h> 2. unsigned char DisBuf8; /全局顯示緩沖區(qū),DisBuf0對應右SLED,DisBuf7對應左SLED, 3. void DisplayBrush( void ) 4. code unsigned char cathode8=0xfe
56、,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f; /陰極控制碼 5. Code unsigned char Seg7Code16= /用十六進數作為數組下標,可直接取得對應的七段編碼字節(jié) 6. 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71; 7. static unsigned char i=0;
57、60;/ (0i7) 循環(huán)刷新顯示,由于是靜態(tài)變量,此賦值只做一次。 8. P2 = 0xff; /顯示消隱,以免下一段碼值顯示在前一支SLED 9. P1 = Seg7Code DisBufi /從顯示緩沖區(qū)取出原始數據,查表變?yōu)槠叨未a后送出顯示 10. P2 = cathode i /將對應陰極置低,顯
58、示 11. if( +i >= 8 ) i=0; /指向下一個數碼管和相應數據 12. 13. void Timer0IntRoute( void ) interrupt 1 14. 15. TL0 = -1000; /由于TL0只有8bits,所以將(-1000)低8位賦給TL0
59、160; 16. TH0 = (-1000)>>8; /?。?1000)的高8位賦給TH0,重新定時1ms 17. DisplayBrush(); 18. 19. void Timer0Init( void ) 20. TMOD=(TMOD & 0xf0) | 0x01; /初始化,定時器T0,工作方式1
60、; 21. TL0 = -1000; /定時1ms 22. TH0 = (-1000)>>8; 23. TR0 = 1; /允許T0開始計數 24. ET0 = 1; /允許T0計數溢出時產生中斷請求 25. 26. void D
61、isplay( unsigned char index, unsigned char dataValue ) DisBuf index = dataValue; 27. void main( void ) 28. 29. unsigned char i; 30. for( i=0; i<
62、;8; i+ ) Display(i, 8-i); /DisBuf0為右,DisBuf7為左 31. Timer0Init(); 32. EA = 1; /允許CPU響應中斷請求 33. While(1); 34. 共9頁: 上一頁 1 2 3 4 5 6 7 8 9 下一頁 第五節(jié):鍵盤驅動指提供一些函數給任務調用,獲取按鍵信息,或讀取按鍵值。定義一
63、個頭文檔 <KEY.H>,描述可用函數,如下:代碼1. #ifndef _KEY_H_ /防止重復引用該文檔,如果沒有定義過符號 _KEY_H_,則編譯下面語句 2. #define _KEY_H_ /只要引用過一次,即 #include <key.h>,則定義符號 _KEY_H_ 3. unsigned char keyHit( void ); /如果按鍵,則返回非
64、,否則返回 4. unsigned char keyGet( void ); /讀取按鍵值,如果沒有按鍵則等待到按鍵為止 5. void keyPut( unsigned char ucKeyVal ); /保存按鍵值ucKeyVal到按鍵緩沖隊列末 6. void keyBack( unsigned char ucKeyVal ); /退回鍵值uc
65、KeyVal到按鍵緩沖隊列首 7. #endif 定義函數體文檔 KEY.C,如下:代碼1. #include “key.h” 2. #define KeyBufSize 16 /定義按鍵緩沖隊列字節(jié)數 3. unsigned char KeyBuf KeyBufSize /定義一個無符號字符數組作為按鍵緩沖隊列。該隊列為先進 4.
66、0; /先出,循環(huán)存取,下標從到 KeyBufSize-1 5. unsigned char KeyBufWp=0; /作為數組下標變量,記錄存入位置 6. unsigned char KeyBufRp=0; /作為數組下標變量,記錄讀出位置 7. /如果存入位置與讀出位置相同,則表明隊列中無按鍵數據 8. unsigned char keyHit(
67、0;void ) 9. if( KeyBufWp = KeyBufRp ) return( 0 ); else return( 1 ); 10. 11. unsigned char keyGet( void ) 12. unsigned char retVal; /暫存
68、讀出鍵值 13. while( keyHit()=0 ); /等待按鍵,因為函數keyHit()的返回值為 0 表示無按鍵 14. retVal = KeyBuf KeyBufRp /從數組中讀出鍵值 15. if( +KeyBufRp >= KeyBufSize ) KeyBufRp=0; /讀位置加,超出隊列則循環(huán)回初始位置
69、; 16. return( retVal ); 17. 18. 19. void keyPut( unsigned char ucKeyVal ) 20. KeyBuf KeyBufWp = ucKeyVal; /鍵值存入數組 21. if( +KeyBufWp >= Key
70、BufSize ) KeyBufWp=0; /存入位置加,超出隊列則循環(huán)回初始位置 22. 23. /* 24. 由于某種原因,讀出的按鍵,沒有用,但其它任務要用該按鍵,但傳送又不方便。此時可以退回按鍵隊列。就如取錯了信件,有必要退回一樣 25. */ 26. void keyBack( unsigned char ucKeyVal ) 27. 28
71、. /* 29. 如果KeyBufRp=0; 減1后則為FFH,大于KeyBufSize,即從數組頭退回到數組尾。或者由于干擾使得KeyBufRp超出隊列位置,也要調整回到正常位置, 30. */ 31. if( -KeyBufRp >= KeyBufSize ) KeyBufRp=KeyBufSize-1; 32. KeyBuf KeyBufRp = ucKeyVal; /回
72、存鍵值 33. 下面漸進講解鍵盤物理層的驅動。電路共同點:P2端口接一共陰數碼管,共陰極接GND,P2.0接a段、P2.1接b段、P2.7接h段。軟件共同點:code unsigned char Seg7Code10 是七段數碼管共陰編碼表。Code unsigned char Seg7Code16=/ 0 1 2 3 4 5
73、160; 6 7 8 9 A b C d E F0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,
74、0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71;例一:P1.0接一按鍵到GND,鍵編號為,顯示按鍵。代碼1. #include <at89x52.h> 2. #include “KEY.H” 3. void main( void ) 4. P1_0 = 1; /作為輸入引腳,必須先輸出高電平 5. while( 1 ) /永遠
75、為真,即死循環(huán) 6. if( P1_0 = 0 ) /如果按鍵,則為低電平 7. keyPut( 6 ); /保存按鍵編號值為按鍵隊列 8. while( P1_0 = 0 ); /如果一直按著鍵,則不停地執(zhí)行該循環(huán),實際是等待松鍵 9. 10. if( keyHit
76、() != 0 ) /如果隊列中有按鍵 11. P2=Seg7Code keyGet() /從隊列中取出按鍵值,并顯示在數碼管上 12. 13. 例二:在例一中考慮按鍵20ms抖動問題。代碼1. #include <at89x52.h> 2. #include “KEY.H” 3. void main(
77、void ) 4. P1_0 = 1; /作為輸入引腳,必須先輸出高電平 5. while( 1 ) /永遠為真,即死循環(huán) 6. if( P1_0 = 0 ) /如果按鍵,則為低電平 7. delay20ms(); /延時20ms,跳過接下抖動 8. keyPut( 6
78、 ); /保存按鍵編號值為按鍵隊列 9. while( P1_0 = 0 ); /如果一直按著鍵,則不停地執(zhí)行該循環(huán),實際是等待松鍵 10. delay20ms(); /延時20ms,跳過松開抖動 11. 12. if( keyHit() != 0 ) /如果隊列中有按鍵 13. P2=Seg7Cod
79、e keyGet() /從隊列中取出按鍵值,并顯示在數碼管上 14. 15. 例三:在例二中考慮干擾問題。即小于20ms的負脈沖干擾。代碼1. #include <at89x52.h> 2. #include “KEY.H” 3. void main( void ) 4. P1_0 = 1;
80、 /作為輸入引腳,必須先輸出高電平 5. while( 1 ) /永遠為真,即死循環(huán) 6. if( P1_0 = 0 ) /如果按鍵,則為低電平 7. delay20ms(); /延時20ms,跳過接下抖動 8. if( P1_0 = 1 ) continue; /假按鍵 &
81、#160; 9. keyPut( 6 ); /保存按鍵編號值為按鍵隊列 10. while( P1_0 = 0 ); /如果一直按著鍵,則不停地執(zhí)行該循環(huán),實際是等待松鍵 11. delay20ms(); /延時20ms,跳過松開抖動 12. 13. if( keyHit() != 0 ) /如果隊列中有按鍵
82、60; 14. P2=Seg7Code keyGet() /從隊列中取出按鍵值,并顯示在數碼管上 15. 16. 例四:狀態(tài)圖編程法。通過20ms周期中斷,掃描按鍵。代碼1. /* 2. 采用晶體為12KHz時,指令周期為1ms(即主頻為1KHz),這樣T0工作在定時器方式2,8位自動重載。計數值為20,即可產生20ms的周期性中斷,在中斷服務程序中實現按鍵掃描 3. */ 4. #include
83、<at89x52.h> 5. #include “KEY.H” 6. void main( void ) 7. 8. TMOD = (TMOD & 0xf0 ) | 0x02; /不改變T1的工作方式,T0為定時器方式2 9. TH0 = -20;
84、 /計數周期為20個主頻脈,即20ms 10. TL0=TH0; /先軟加載一次計數值 11. TR0=1; /允許T0開始計數 12. ET0=1; /允許T0計數溢出時產生中斷請求 13. EA=1;
85、/允許CPU響應中斷請求 14. while( 1 ) /永遠為真,即死循環(huán) 15. 16. if( keyHit() != 0 ) /如果隊列中有按鍵 17. P2=Seg7Code keyGet() /從隊列中取出按鍵值,并顯示在數碼管上 18. 19. 20. void&
86、#160;timer0int( void ) interrupt 1 /20ms;T0的中斷號為1 21. static unsigned char sts=0; 22. P1_0 = 1; /作為輸入引腳,必須先輸出高電平 23. switch( sts ) 24. 25.
87、 case 0: if( P1_0=0 ) sts=1; break; /按鍵則轉入狀態(tài)1 26. case 1: 27. if( P1_0=1 ) sts=0; /假按錯,或干擾,回狀態(tài)0 28. else sts=2; keyPut( 6 ); /確實按鍵,鍵值入隊列,并轉狀態(tài)2
88、0; 29. break; 30. case 2: if( P1_0=1 ) sts=3; break; /如果松鍵,則轉狀態(tài)3 31. case 3: 32. if( P1_0=0 ) sts=2; /假松鍵,回狀態(tài)2 33. e
89、lse sts=0; /真松鍵,回狀態(tài)0,等待下一次按鍵過程 34. 35. 例五:狀態(tài)圖編程法。代碼1. /* 2. 如果采用晶體為12MHz時,指令周期為1us(即主頻為1MHz),要產生20ms左右的計時,則計數值達到20000,T0工作必須為定時器方式1,16位非自動重載,即可產生20ms的周期性中斷,在中斷服務程序中實現按鍵掃描 3. */ 4. #include
90、 <at89x52.h> 5. #include “KEY.H” 6. void main( void ) 7. 8. TMOD = (TMOD & 0xf0 ) | 0x01; /不改變T1的工作方式,T0為定時器方式1 9. TL0 = -20000;
91、60; /計數周期為20000個主頻脈,自動取低8位 10. TH0 = (-20000)>>8; /右移8位,實際上是取高8位 11. TR0=1; /允許T0開始計數 12. ET0=1; /允許T0計數溢出時產生中斷請求 13. EA=1;
92、; /允許CPU響應中斷請求 14. while( 1 ) /永遠為真,即死循環(huán) 15. 16. if( keyHit() != 0 ) /如果隊列中有按鍵 17. P2=Seg7Code keyGet() /從隊列中取出按鍵值,并顯示在數碼管上 18.
93、160; 19. 20. void timer0int( void ) interrupt 1 /20ms;T0的中斷號為1 21. static unsigned char sts=0; 22. TL0 = -20000; /方式1為軟件重載 23. TH0 = (-20000)>>8; /右移8位,實際上是取高8位 24. P1_0 = 1; /作為輸入引腳,必須先輸出高電平 25. switch( sts ) 26. 27. case 0: if( P1_0=
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版圍欄生產廢水處理與排放標準合同3篇
- 二零二五版?zhèn)€人專利權抵押融資合同模板2篇
- 二零二五版股權質押投資顧問服務合同樣本3篇
- 二零二五年藝術展廳租賃及藝術品交易服務合同3篇
- 二零二五版國際貿易實務實驗報告與國際貿易實務指導合同3篇
- 二零二五版電商企業(yè)內部保密協(xié)議及商業(yè)秘密保密制度合同2篇
- 二零二五年度高校教師解聘合同3篇
- 二零二五版屋頂光伏發(fā)電與防水一體化系統(tǒng)合同3篇
- 二零二五版上市公司短期融資券發(fā)行合同3篇
- 二零二五版企業(yè)財務風險管理體系構建服務合同2篇
- DB-T29-74-2018天津市城市道路工程施工及驗收標準
- 小學一年級20以內加減法混合運算3000題(已排版)
- 智慧工廠數字孿生解決方案
- 病機-基本病機 邪正盛衰講解
- 品管圈知識 課件
- 非誠不找小品臺詞
- 2024年3月江蘇省考公務員面試題(B類)及參考答案
- 患者信息保密法律法規(guī)解讀
- 老年人護理風險防控PPT
- 充電樁采購安裝投標方案(技術方案)
- 醫(yī)院科室考勤表
評論
0/150
提交評論