![51單片機(jī)C語(yǔ)言學(xué)習(xí)資料_第1頁(yè)](http://file2.renrendoc.com/fileroot_temp3/2021-11/17/b432600e-1bc1-4a54-8c64-5f7d5af9372c/b432600e-1bc1-4a54-8c64-5f7d5af9372c1.gif)
![51單片機(jī)C語(yǔ)言學(xué)習(xí)資料_第2頁(yè)](http://file2.renrendoc.com/fileroot_temp3/2021-11/17/b432600e-1bc1-4a54-8c64-5f7d5af9372c/b432600e-1bc1-4a54-8c64-5f7d5af9372c2.gif)
![51單片機(jī)C語(yǔ)言學(xué)習(xí)資料_第3頁(yè)](http://file2.renrendoc.com/fileroot_temp3/2021-11/17/b432600e-1bc1-4a54-8c64-5f7d5af9372c/b432600e-1bc1-4a54-8c64-5f7d5af9372c3.gif)
![51單片機(jī)C語(yǔ)言學(xué)習(xí)資料_第4頁(yè)](http://file2.renrendoc.com/fileroot_temp3/2021-11/17/b432600e-1bc1-4a54-8c64-5f7d5af9372c/b432600e-1bc1-4a54-8c64-5f7d5af9372c4.gif)
![51單片機(jī)C語(yǔ)言學(xué)習(xí)資料_第5頁(yè)](http://file2.renrendoc.com/fileroot_temp3/2021-11/17/b432600e-1bc1-4a54-8c64-5f7d5af9372c/b432600e-1bc1-4a54-8c64-5f7d5af9372c5.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、51單片機(jī)C語(yǔ)言學(xué)習(xí)資料目 錄前言 錯(cuò)誤! 未定義書(shū)簽基礎(chǔ)知識(shí):?jiǎn)纹瑱C(jī)編程基礎(chǔ) 2第一節(jié):?jiǎn)螖?shù)碼管按鍵顯示 4第二節(jié):雙數(shù)碼管可調(diào)秒表 6第三節(jié):十字路口交通燈 6第四節(jié):數(shù)碼管驅(qū)動(dòng) 8第五節(jié):鍵盤驅(qū)動(dòng) 9第六節(jié):低頻頻率計(jì) 15第七節(jié):電子表 18第八節(jié):串行口應(yīng)用 19基礎(chǔ)知識(shí):?jiǎn)纹瑱C(jī)編程基礎(chǔ)單片機(jī)的外部結(jié)構(gòu):1、DIP40雙列直插;2、 P0, P1, P2, P3四個(gè)8位準(zhǔn)雙向I/O弓I腳;(作為I/O輸入時(shí),要先輸出高電平)3、電源 VCC( PIN40)和地線 GND( PIN20);4、 高電平復(fù)位RESET( PIN9); ( 10uF電容接VC勇 RESET即可實(shí)現(xiàn)上電復(fù)位)
2、5、 內(nèi)置振蕩電路,外部只要接晶體至X1 (PIN18)和X0 (PIN19);(頻率為主頻的12倍)6、程序配置EA (PIN31)接高電平VCC (運(yùn)行單片機(jī)內(nèi)部 RO附的程序)7、P3 支持第二功能:RXD TXD INT0、INT1、T0、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 SBUF4、 一個(gè)中斷控制器;(IE , IP)針對(duì)AT89C52單
3、片機(jī),頭文件 AT89x52.h給出了 SFR特殊功能寄存器所有端口的定義。教科書(shū)的160頁(yè)給出了針對(duì)MCS51系列單片機(jī)的C語(yǔ)言擴(kuò)展變量類型。C語(yǔ)言編程基礎(chǔ):1、 十六進(jìn)制表示字節(jié) 0x5a:二進(jìn)制為 01011010B; 0x6E為01101110。2、 如果將一個(gè)16位二進(jìn)數(shù)賦給一個(gè)8位的字節(jié)變量,則自動(dòng)截?cái)酁榈?位,而丟掉高8位。3、 +var表示對(duì)變量 var先增一;var 表示對(duì)變量后減一。4、 x |= 0x0f; 表示為 x = x | 0x0f;5、 TMOD = ( TMOD & 0xf0 ) | 0x05;表示給變量 TMOD勺低四位賦值 0x5,而不改變 TMO
4、D勺高四位。6、 While( 1 );表示無(wú)限執(zhí)行該語(yǔ)句,即死循環(huán)。語(yǔ)句后的分號(hào)表示空循環(huán)體,也就是 ;在某引腳輸出高電平的編程方法:(比如P1.3 (PIN4)引腳)#include <AT89x52.h>/該頭文檔中有單片機(jī)內(nèi)部資源的符號(hào)化定義,其中包含P1.3void main( void )/void表示沒(méi)有輸入?yún)?shù),也沒(méi)有函數(shù)返值,這入單片機(jī)運(yùn)行的復(fù)位入口P1_3 = 1;/給P1_3賦值1,引腳P1.3就能輸出高電平 VCCWhile( 1 );/ 死循環(huán),相當(dāng) LOOP: goto LOOP;注意:P0的每個(gè)引腳要輸出高電平時(shí),必須外接上拉電阻(如4K70至VCOt
5、源在某引腳輸出低電平的編程方法:(比如P2.7引腳)#include <AT89x52.h>/該頭文檔中有單片機(jī)內(nèi)部資源的符號(hào)化定義,其中包含 P2.7void main( void )/void表示沒(méi)有輸入?yún)?shù),也沒(méi)有函數(shù)返值,這入單片機(jī)運(yùn)行的復(fù)位入口P2_7 = 0;/給P2_7賦值0,引腳P2.7就能輸出低電平 GNDWhile( 1 );/ 死循環(huán),相當(dāng) LOOP: goto LOOP;)在某引腳輸出方波編程方法:(比如P3.1引腳)#include <AT89x52.h>/該頭文檔中有單片機(jī)內(nèi)部資源的符號(hào)化定義,其中包含 P3.1void main( void
6、 )/void 表示沒(méi)有輸入?yún)?shù),也沒(méi)有函數(shù)返值,這入單片機(jī)運(yùn)行的復(fù)位入口While( 1 )/非零表示真,如果為真則執(zhí)行下面循環(huán)體的語(yǔ)句P3_1 = 1;/給P3_1賦值1,引腳P3.1就能輸出高電平 VCCP3_1 = 0;/給P3_1賦值0,引腳P3.1就能輸出低電平 GND)/由于一直為真,所以不斷輸出高、低、高、低,從而形成方波)將某引腳的輸入電平取反后,從另一個(gè)引腳輸出:(比如P0.4 = NOT( P1.1)#include <AT89x52.h>/該頭文檔中有單片機(jī)內(nèi)部資源的符號(hào)化定義,其中包含 P0.4和P1.1void main( void )/void表示沒(méi)有
7、輸入?yún)?shù),也沒(méi)有函數(shù)返值,這入單片機(jī)運(yùn)行的復(fù)位入口P1_1 = 1;/初始化。P1.1作為輸入,必須輸出高電平While( 1 )/非零表示真,如果為真則執(zhí)行下面循環(huán)體的語(yǔ)句if(P1_1 =1)P0_4=0;else/P0_4=0;P0_4=1;/讀取P1.1,就是認(rèn)為P1.1為輸入,如果P1.1輸入高電平VCC)/給P0_4賦值0,引腳P0.4就能輸出低電平 GND/否則P1.1輸入為低電平GND)/給P0_4賦值0,引腳P0.4就能輸出低電平 GND)/給P0_4賦值1,引腳P0.4就能輸出高電平 VCC/由于一直為真,所以不斷根據(jù)P1.1的輸入情況,改變 P0.4的輸出電平8個(gè)引腳輸出
8、:(比如P2 = NOT( P3 )將某端口 8個(gè)引腳輸入電平,低四位取反后,從另一個(gè)端口#include <AT89x52.h>/該頭文檔中有單片機(jī)內(nèi)部資源的符號(hào)化定義,其中包含 P2和P3void main( void )/void表示沒(méi)有輸入?yún)?shù),也沒(méi)有函數(shù)返值,這入單片機(jī)運(yùn)行的復(fù)位入口P3 = 0xff;/初始化。P3作為輸入,必須輸出高電平,同時(shí)給 P3 口的8個(gè)引腳輸出高電平While( 1 )/非零表示真,如果為真則執(zhí)行下面循環(huán)體的語(yǔ)句/取反的方法是異或1,而不取反的方法則是異或0P2 = P3A0x0f/讀取P3,就是認(rèn)為P3為輸入,低四位異或者1,即取反,然后輸出
9、)/由于一直為真,所以不斷將P3取反輸出到P2注意:一個(gè)字節(jié)的8位DX D6至D0,分另U輸出至U P3.7、P3.6至P3.0,比如P3=0x0f,貝U P3.7、P3.6、P3.5、P3.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。第一節(jié):?jiǎn)螖?shù)碼管按鍵顯示單片機(jī)最小系統(tǒng)的硬件原理接線圖:1、接電源:VCC( PIN40)、GND( PIN20)。加接退耦電容 0.1uF2、接晶體:X1 (PIN18)、X2 (PIN19)。注意標(biāo)出晶體頻率(選用 1
10、2MH0,還有輔助電容30pF3、接復(fù)位:RES( PIN9)。接上電復(fù)位電路,以及手動(dòng)復(fù)位電路,分析復(fù)位工作原理4、接配置:EA (PIN31 )。說(shuō)明原因。發(fā)光二極的控控制:?jiǎn)纹瑱C(jī) I/O輸出將一發(fā)光二極管LED的正極(陽(yáng)極)接 P1.1 , LED的負(fù)極(陰極)接地 GND只要P1.1輸出高電平VCCLED就正向?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é)果L
11、ED不亮。開(kāi)關(guān)雙鍵的輸入:輸入先輸出高 一個(gè)按鍵 KEY_。隈在P1.6與GN比間,另一個(gè)按鍵 KEY_OF嵌P1.7與GN龍間,按 KEY_O距LED亮,按KEY OF后LED滅。同時(shí)按下LED半亮,LED保持后松開(kāi)鍵的狀態(tài),即 ON OFF滅。#include <at89x52.h>#define LEDP1A1#define KEY_ONP"6#define KEY_OFFP"7void main( void )/用符號(hào)LED弋替P1_1/用符號(hào) KEY_O玳替P1_6/用符號(hào) KEY_OF戰(zhàn)替P1_7/單片機(jī)復(fù)位后的執(zhí)行入口,void表示空,無(wú)輸入?yún)?shù),
12、無(wú)返回值KEY_ON = 1;KEY_OFF = 1;While( 1 )/作為輸入,/作為輸入,/永遠(yuǎn)為真,首先輸出高,接下 KEY_ON P1.6則接地為0,否則輸入為1 首先輸出高,接下 KEY_OFF P1.7則接地為0,否則輸入為1 所以永遠(yuǎn)循環(huán)執(zhí)行如下括號(hào)內(nèi)所有語(yǔ)句(if( KEY_ON=0 )LED=1;/ 是 KEY_O概下,所示 P1.1 輸出高,LED亮if( KEY_OFF=0 )LED=0;/ 是 KEY_OF眠下,所示 P1.1 輸出低,LED滅)/松開(kāi)鍵后,都不給LED賦值,所以LED保持最后按鍵狀態(tài)。/同時(shí)按下時(shí),LED不斷亮滅,各占一半時(shí)間,交替頻率很快,由于人
13、眼慣性,看上去為半亮態(tài)數(shù)碼管的接法和驅(qū)動(dòng)原理一支七段數(shù)碼管實(shí)際由8個(gè)發(fā)光二極管構(gòu)成,其中 7個(gè)組形構(gòu)成數(shù)字8的七段筆畫(huà),所以稱為七段數(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的頂上一畫(huà),按順時(shí)針?lè)较蚺?,中間一畫(huà)為g,小數(shù)點(diǎn)為ho我們通常又將各二極與一個(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)字
14、節(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個(gè)發(fā)光二極管的負(fù)極(陰極)內(nèi)接在一起,作為數(shù)碼管的一個(gè)引腳,這種數(shù)碼管則被稱為共陰數(shù)碼管,共同的引 腳則稱為共陰極,8 個(gè)正極則為段極。否 則,如果是將正極(陽(yáng)極)內(nèi)接在一起 引出的,則稱為共陽(yáng) 數(shù)碼管,共同的引腳 則稱為共陽(yáng)極,8個(gè) 負(fù)極則為段極。以單支共陰數(shù) 碼管為例,可將段極 接到某端口 Pn,共陰 極接GND則可編寫(xiě) 出對(duì)應(yīng)十六進(jìn)制碼靠示字符共陰(ft段選碼共陽(yáng)橫段逃牌顯示字符技兩欖段蹄回03FHCOMC39H
15、C6H1Q6HF9HD1EHA1H25BHA4HE79H86H3垂HBOHF71H34H466H99HP73H32H56DHu3EHC1H67DH32Hr31HCEH107HF?H76EHP1H87FH30H8FFHOOH96FH煩”O(jiān)OHFFHA湖B?CH33H的七段碼表字節(jié)數(shù)據(jù)如右圖:16鍵碼顯示的程序我們?cè)赑1端口接一支共陰數(shù)碼管SLED在P2、P3端口接16個(gè)按鍵,分別編號(hào)為 KEY_Q KEY_1到KEY_F操作時(shí)只能按一個(gè)鍵,按鍵后SLED顯示對(duì)應(yīng)鍵編號(hào)。#include <at89x52.h>#define SLED P1#define KEY_0 P2A0#defi
16、ne KEY_1 P2A1#define KEY_2 P2A2#define KEY_3 P2A3#define KEY_4 P2A4#define KEY_5 P2A5#define KEY_6 P2A6#define KEY_7 P2A7#define KEY_8 P3A0#define KEY_9 P3A1#define KEY_A P3A2#define KEY_B P3A3#define KEY_C P3A4#define KEY_D P3A5#define KEY_E P3A6#define KEY_F P3A7Code unsigned char Seg7Code16= /用十六
17、進(jìn)數(shù)作為數(shù)組下標(biāo),可直接取得對(duì)應(yīng)的七段編碼字節(jié)/ 01 234 5 6 7 8 9 A b C d E F(0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71);void main( void )(unsigned char i=0;/ 作為數(shù)組下標(biāo)P2 = 0xff; /P2作為輸入,初始化輸出高P3 = 0xff; /P3作為輸入,初始化輸出高While( 1 )( if( KEY_0 = 0 ) i=0;if( KEY_1 = 0 ) i=1;if(
18、KEY_2 = 0 ) i=2;if( KEY_3 = 0 ) i=3;if( KEY_4 = 0 ) i=4;if( KEY_5 = 0 ) i=5;if( KEY_6 = 0 ) i=6;if( KEY_7 = 0 ) i=7;if( KEY_8 = 0 ) i=8;if( KEY_9 = 0 ) i=9;if( KEY_A = 0 ) i=0xA;if( KEY_B = 0 )i=0xB;if( KEY_C = 0 ) i=0xC;if( KEY_D = 0 )i=0xD;if( KEY_E = 0 ) i=0xE;if( KEY_F = 0 )i=0xF;SLED = Seg7Code
19、 i ;/開(kāi)始時(shí)顯示0,根據(jù)i取應(yīng)七段編碼 第二節(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è)位。編得如下程序: #include <at89x52.h>C
20、ode unsigned char Seg7Code16= /用十六進(jìn)數(shù)作為數(shù)組下標(biāo),可直接取得對(duì)應(yīng)的七段編碼字節(jié)/ 01 234 5 6 7 89 A b C d E F(0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71; void main( void ) (unsigned int us250 = 0;unsigned char s10 = 0;unsigned char s1 = 0;unsigned char key10 = 0;/記憶按鍵狀態(tài),
21、為 1按下unsigned char key1 = 0;/記憶按鍵狀態(tài),為 1按下/初始化定時(shí)器Timer0TMOD = (TMOD & 0xF0) | 0x02;TH1 = -250;/對(duì)于8位二進(jìn)數(shù)來(lái)說(shuō),-250=6,也就是加 250次1時(shí)為256,即為0TR1 = 1;while(1)(/ 循環(huán) 1P1 = Seg7Code s10 ;/ 顯示秒十位P2 = Seg7Code s1 ;/ 顯示秒個(gè)位while( 1 )(/ 循環(huán) 2/計(jì)時(shí)處理if( TF0 = 1 )(TF0 = 0;if( +us250 >= 4000 )(us250 = 0;if( +s1 >=
22、10 )(si = 0;if( +s10 >= 6 ) s10 = 0;)break; /結(jié)束"循環(huán)2”,修改顯示)/按十位鍵處理P3.2 = 1;/P3.2 作為輸入,先要輸出高電平if( key10 = 1 )(/ 等松鍵if( P3.2 = 1 )key10=0;)else(/未按鍵if( P3.2 = 0 )(key10 = 1;if( +s10 >= 6 ) s10 = 0;break; /結(jié)束"循環(huán)2”,修改顯示)/按個(gè)位鍵處理P3.3 = 1;/P3.3作為輸入,先要輸出高電平if( key1 = 1 )/ 等松鍵( if( P3.3 = 1 )k
23、ey1=0;else (/未按鍵if( P3.3 = 0 )( key1 = 1;if( +s1 >= 10 ) s1 = 0;break; /結(jié)束"循環(huán)2”,修改顯示 / 循環(huán) 2' end/ 循環(huán) 1' end/main ' end第三節(jié):十字路口交通燈如果一個(gè)單位時(shí)間為1秒,這里設(shè)定的十字路口交通燈按如下方式四個(gè)步驟循環(huán)工作:60個(gè)單位時(shí)間,南北紅,東西綠;10個(gè)單位時(shí)間,南北紅,東西黃;60個(gè)單位時(shí)間,南北綠,東西紅;10個(gè)單位時(shí)間,南北黃,東西紅;解:用P1端口的6個(gè)引腳控制交通燈,高電平燈亮,低電平燈滅。#include <at89x5
24、2.h>/sbit用來(lái)定義一個(gè)符號(hào)位地址,方便編程,提高可讀性,和可移植性sbit SNRed=P1A0;/南北方向紅燈sbit SNYellow =P1A1;/南北方向黃燈sbit SNGreen =P1A2;/南北方向綠燈sbit EWRed=P1A3;/東西方向紅燈sbit EWYellow =P"4;/東西方向黃燈sbit EWGreen =P1A5;/東西方向綠燈/*用軟件產(chǎn)生延時(shí)一個(gè)單位時(shí)間void Delay1Unit( void )unsigned int i, j;for( i=0; i<1000; i+ )*/for( j<0; j<100
25、0; j+ );/通過(guò)實(shí)測(cè),調(diào)整j循環(huán)次數(shù),產(chǎn)生1ms延時(shí)/還可以通過(guò)生成匯編程序來(lái)計(jì)算指令周期數(shù),結(jié)合晶體頻率來(lái)調(diào)整j循環(huán)次數(shù),接近1ms/*延時(shí)n個(gè)單位時(shí)間*/void Delay( unsigned int n ) for( ; n!=0; n- ) Delay1Unit(); void main( 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; E
26、WGreen=0; Delay( 10 );SNRed=1; SNYellow=0; SNGreen=0; EWRed=0; EWYellow=0; EWGreen=1; Delay( 60 );SNRed=1; SNYellow=0; SNGreen=0; EWRed=0; EWYellow=1; EWGreen=0; Delay( 10 ); 第四節(jié):數(shù)碼管驅(qū)動(dòng)顯示 “ 12345678”P1端口接8聯(lián)共陰數(shù)碼管SLED8的段極:P1.7接段h, , , P1.0接段aP2端口接8聯(lián)共陰數(shù)碼管SLED8的段極:P2.7接左邊的共陰極,P2.0接右邊的共陰極方案說(shuō)明:晶振頻率fosc=12M
27、Hz,數(shù)碼管采用動(dòng)態(tài)刷新方式顯示,在1ms定時(shí)斷服務(wù)程序中實(shí)現(xiàn)#include <at89x92.h>unsigned char DisBuf8;全局顯示緩沖區(qū),DisBuf0對(duì)應(yīng)右 SLED DisBuf7 對(duì)應(yīng)左 SLEDvoid DisplayBrush( void ) code unsigned char cathode8=0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f;/ 陰極控制碼Code unsigned char Seg7Code16= /用十六進(jìn)數(shù)作為數(shù)組下標(biāo),可直接取得對(duì)應(yīng)的七段編碼字節(jié)0x3f,0x06,0x5b,0x4f,0x
28、66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;static unsigned char i=0; /(0v i < 7) 循環(huán)刷新顯示,由于是靜態(tài)變量,此賦值只做一次。P2 = 0xff;/顯示消隱,以免下一段碼值顯示在前一支SLEDP1 = Seg7Code DisBufi ; /從顯示緩沖區(qū)取出原始數(shù)據(jù),查表變?yōu)槠叨未a后送出顯示P2 = cathode i ;/將對(duì)應(yīng)陰極置低,顯示if( +i >= 8 ) i=0;/指向下一個(gè)數(shù)碼管和相應(yīng)數(shù)據(jù) void Timer0IntRoute( void ) inte
29、rrupt 1 TL0 = -1000;/由于TL0只有8bits,所以將(-1000 )低8位賦給TL0TH0 = (-1000)>>8;/ 取(-1000)的高 8 位賦給 TH0,重新定時(shí) 1msDisplayBrush(); void Timer0Init( void ) TMOD=(TMOD & 0xf0) | 0x01;/初始化,定時(shí)器 T0,工作方式1TL0 = -1000 ; / 定時(shí) 1msTH0 = (-1000)>>8;TR0 = 1;/允許T0開(kāi)始計(jì)數(shù)ET0 = 1;/允許T0計(jì)數(shù)溢出時(shí)產(chǎn)生中斷請(qǐng)求 void Display( unsig
30、ned char index, unsigned char dataValue ) DisBuf index = dataValue; void main( void ) unsigned char i;for( i=0; i<8; i+ ) Display(i, 8-i); /DisBuf0為右,DisBuf7 為左Timer0Init();EA = 1 ;/允許CPU響應(yīng)中斷請(qǐng)求While(1); 第五節(jié):鍵盤驅(qū)動(dòng)指提供一些函數(shù)給任務(wù)調(diào)用,獲取按鍵信息,或讀取按鍵值。 定義一個(gè)頭文檔<KEY.H>,描述可用函數(shù),如下:#ifndef _KEY_H_/防止重復(fù)引用該文檔,如
31、果沒(méi)有定義過(guò)符號(hào)_KEY_H_,則編譯下面語(yǔ)句#define _KEY_H_/ 只要引用過(guò)一次,即 #include <key.h> ,則定義符號(hào) _KEY_H_unsigned char keyHit( void );/如果按鍵,則返回非0,否則返回0unsigned char keyGet( void );/讀取按鍵值,如果沒(méi)有按鍵則等待到按鍵為止void keyPut( unsigned char ucKeyVal );/ 保存按鍵值 ucKeyVal 到按鍵緩沖隊(duì)列末void keyBack( unsigned char ucKeyVal );/ 退回鍵值 ucKeyVal
32、 到按鍵緩沖隊(duì)列首#endif定義函數(shù)體文檔KEY.C ,如下:# include " key.h ”#define KeyBufSize 16 /定義按鍵緩沖隊(duì)列字節(jié)數(shù)unsigned char KeyBuf KeyBufSize ;/定義一個(gè)無(wú)符號(hào)字符數(shù)組作為按鍵緩沖隊(duì)列。該隊(duì)列為先進(jìn)/先出,循環(huán)存取,下標(biāo)從0到 KeyBufSize-1unsigned char KeyBufWp=0; /作為數(shù)組下標(biāo)變量,記錄存入位置unsigned char KeyBufRp=0; /作為數(shù)組下標(biāo)變量,記錄讀出位置/如果存入位置與讀出位置相同,則表明隊(duì)列中無(wú)按鍵數(shù)據(jù)unsigned char
33、 keyHit( void ) if( KeyBufWp = KeyBufRp ) return( 0 ); else return( 1 ); unsigned char keyGet( void ) unsigned char retVal; / 暫存讀出鍵值while( keyHit()=0 );等待按鍵,因?yàn)楹瘮?shù)keyHit()的返回值為0表示無(wú)按鍵retVal = KeyBuf KeyBufRp ;/ 從數(shù)組中讀出鍵值if( +KeyBufRp >= KeyBufSize ) KeyBufRp=0;/讀位置加1 ,超出隊(duì)列則循環(huán)回初始位置return( retVal ); vo
34、id keyPut( unsigned char ucKeyVal ) KeyBuf KeyBufWp = ucKeyVal; / 鍵值存入數(shù)組if( +KeyBufWp >= KeyBufSize ) KeyBufWp=0;/存入位置加1 ,超出隊(duì)列則循環(huán)回初始位置 /*由于某種原因,讀出的按鍵,沒(méi)有用,但其它任務(wù)要用該按鍵,但傳送又不方便。此時(shí)可以退回按鍵隊(duì)列。 就如取錯(cuò)了信件,有必要退回一樣*/void keyBack( unsigned char ucKeyVal )/*如果KeyBufRp=0;減1后則為FFH,大于KeyBufSize,即從數(shù)組頭退回到數(shù)組尾。或者由于干擾使得
35、KeyBufRp超出隊(duì)列位置,也要調(diào)整回到正常位置,*/if( -KeyBufRp >= KeyBufSize ) KeyBufRp=KeyBufSize-1;KeyBuf KeyBufRp = ucKeyVal; / 回存鍵值下面漸進(jìn)講解鍵盤物理層的驅(qū)動(dòng)。電路共同點(diǎn):P2端口接一共陰數(shù)碼管,共陰極接 GND P2.0接a段、P2.1接b段、,、P2.7接h段。軟件共同點(diǎn):code unsigned char Seg7Code10是七段數(shù)碼管共陰編碼表。Code unsigned char Seg7Code16=/ 0123456789 A b C d EF0x3f,0x06, 0x5b
36、,0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f,0x6f,0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71;例一:P1.0接一按鍵到GND鍵編號(hào)為6',顯示按鍵#include <at89x52.h>#include“KEY.H' void main( void )(P1_0 = 1;/作為輸入引腳,必須先輸出高電平while( 1 )/永遠(yuǎn)為真,即死循環(huán)( if( P1_0 = 0 )/如果按鍵,則為低電平( keyPut( 6 );/保存按鍵編號(hào)值為按鍵隊(duì)列while( P1_0 = 0 );/如果一直按著鍵,則不停地
37、執(zhí)行該循環(huán),實(shí)際是等待松鍵)if( keyHit() != 0 )/如果隊(duì)列中有按鍵P2=Seg7Code keyGet() ;/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上) )例二:在例一中考慮按鍵20m s抖動(dòng)問(wèn)題。#include <at89x52.h>#include“KEY.H'void main( void )(P1_0 = 1;/作為輸入引腳,必須先輸出高電平while( 1 )/永遠(yuǎn)為真,即死循環(huán)( if( P1_0 = 0 )/如果按鍵,則為低電平 delay20ms(); /延時(shí)20ms跳過(guò)接下抖動(dòng)keyPut( 6 );/保存按鍵編號(hào)值為按鍵隊(duì)列while(
38、 P1_0 = 0 );/如果一直按著鍵,則不停地執(zhí)行該循環(huán),實(shí)際是等待松鍵delay20ms(); /延時(shí)20ms跳過(guò)松開(kāi)抖動(dòng) ) if( keyHit() != 0 )/如果隊(duì)列中有按鍵P2=Seg7Code keyGet() ;/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上) )例三:在例二中考慮干擾問(wèn)題。即小于20ms的負(fù)脈沖干擾。#include <at89x52.h>#include“KEY.H'void main( void )(P1_0 = 1;/作為輸入引腳,必須先輸出高電平while( 1 )/永遠(yuǎn)為真,即死循環(huán)( if( P1_0 = 0 )/如果按鍵,則為低
39、電平( delay20ms(); /延時(shí)20ms,跳過(guò)接下抖動(dòng)if( P1 0 = 1 ) continue; / 假按鍵keyPut( 6 );/保存按鍵編號(hào)值為按鍵隊(duì)列while( P1_0 = 0 );/如果一直按著鍵,則不停地執(zhí)行該循環(huán),實(shí)際是等待松鍵delay20ms();/延時(shí)20ms,跳過(guò)松開(kāi)抖動(dòng)) if( keyHit() != 0 )/如果隊(duì)列中有按鍵P2=Seg7Code keyGet() ;/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上) )例四:狀態(tài)圖編程法。通過(guò) 20ms周期中斷,掃描按鍵。/*采用晶體為12KHz時(shí),指令周期為1ms (即主頻為1KHz),這樣T0工作在定時(shí)
40、器方式2, 8位自動(dòng)重載。 計(jì)數(shù)值為20,即可產(chǎn)生20ms的周期性中斷,在中斷服務(wù)程序中實(shí)現(xiàn)按鍵掃描*/ #include <at89x52.h>#include“KEY.H'void main( void )TMOD = (TMOD & 0xf0 ) | 0x02;/TH0 = -20;/TL0=TH0;/不改變T1的工作方式,T0為定時(shí)器方式2 計(jì)數(shù)周期為20個(gè)主頻脈,即20ms先軟加載一次計(jì)數(shù)值TR0=1;/允許T0開(kāi)始計(jì)數(shù)ET0=1;/允許T0計(jì)數(shù)溢出時(shí)產(chǎn)生中斷請(qǐng)求EA=1;/允許CPUP向應(yīng)中斷請(qǐng)求while( 1 ) (永遠(yuǎn)為真,即死循環(huán)if( keyH
41、it() != 0 )/如果隊(duì)列中有按鍵P2=Seg7Code keyGet();/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上void timer0int( void ) interrupt 1/20ms ; T0的中斷號(hào)為1( static unsigned char sts=0;P1_0 = 1;作為輸入引腳,必須先輸出高電平switch( sts )/按鍵則轉(zhuǎn)入狀態(tài)1(case 0: if( P1_0=0 ) sts=1; break;case 1:if( P1_0=1 ) sts=0;/else( sts=2; keyPut( 6 ); /假按錯(cuò),或干擾,回狀態(tài) 0確實(shí)按鍵,鍵值入隊(duì)列,并轉(zhuǎn)
42、狀態(tài) 2break;case 2: if( P1_0=1 ) sts=3; break;/如果松鍵,則轉(zhuǎn)狀態(tài)3case 3:if( P1_0=0 ) sts=2;/假松鍵,回狀態(tài)else sts=0;/真松鍵,回狀態(tài)0,等待下一次按鍵過(guò)程例五:狀態(tài)圖編程法。/*如果采用晶體為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)按鍵掃描*/ #include <at89x52.h>#include“KEY.H'void main
43、( void )TMOD = (TMOD & 0xf0 ) | 0x01;/不改變T1的工作方式,T0為定時(shí)器方式1TL0 = -20000;/TH0 = (-20000)>>8;/TR0=1;/計(jì)數(shù)周期為20000個(gè)主頻脈,自動(dòng)取低 8位右移8位,實(shí)際上是取高8位允許T0開(kāi)始計(jì)數(shù)ET0=1;/允許T0計(jì)數(shù)溢出時(shí)產(chǎn)生中斷請(qǐng)求EA=1;/允許CPUP向應(yīng)中斷請(qǐng)求while( 1 )/永遠(yuǎn)為真,即死循環(huán)if( keyHit() != 0 )/如果隊(duì)列中有按鍵P2=Seg7Code keyGet();/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上void timer0int( void
44、) interrupt 1 ( static unsigned char sts=0;/20ms ; T0的中斷號(hào)為1TL0 = -20000;/方式1為軟件重載TH0 = (-20000)>>8;P1_0 = 1;/右移8位,實(shí)際上是取局/作為輸入引腳,必須先輸出高電平switch( sts )case 0: if( P1_0=0 ) sts=1; break;/按鍵則轉(zhuǎn)入狀態(tài)case 1:if( P1_0=1 ) sts=0;/else( sts=2; keyPut( 6 ); / break;假按錯(cuò),或干擾,回狀態(tài) 0確實(shí)按鍵,鍵值入隊(duì)列,并轉(zhuǎn)狀態(tài) 2case 2: if(
45、P1_0=1 ) sts=3; break;/如果松鍵,則轉(zhuǎn)狀態(tài)3case 3:if( P1_0=0 ) sts=2;/else sts=0;/假松鍵,回狀態(tài)真松鍵,回狀態(tài)0,等待下一次按鍵過(guò)程例六:4X4按鍵。/*由P1端口的高4位和低4位構(gòu)成4X4的矩陣鍵盤,本程序只認(rèn)為單鍵操作為合法,同時(shí)按多鍵時(shí)無(wú)效。這樣下面的X, 丫的合法值為0x7, 0xb, 0xd, 0xe, 0xf,通過(guò)表keyCode影射變換可得按鍵值*#include <at89x52.h>#incudeaKEY.H,unsigned char keyScan( void )/返回0表示無(wú)按鍵,或無(wú)效按鍵,其它
46、值為按鍵編碼值 code unsigned char keyCode16=/0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 4, 0 );unsigned char x, y, retVal;P1=0x0f;/低四位輸入,高四位輸出 0x=P1&0x0f;/P1輸入后,清高四位,作為X值P1=0xf0;/高四位輸入,低四位輸出 0y=(P1 >> 4)& 0x0f;/P1輸入
47、后移位到低四位,并清高四位,作為 丫值retVal = keyCodex*4 + keyCodey;/根據(jù)本公式倒算按鍵編碼if( retVal=0 ) return(0); else return( retVal-4 );)/比如按鍵1 ',得X=0x7, Y=0x7,算得retVal= 5 ,所以返回函數(shù)值 1。/雙如按鍵7',得X=0xb, Y=0xd,算得retVal=11 ,所以返回函數(shù)值 7。void main( void )TMOD = (TMOD & 0xf0) | 0x01;/不改變T1的工作方式,T0為定時(shí)器方式1TL0 = -20000;/計(jì)數(shù)周期
48、為20000個(gè)主頻脈,自動(dòng)取低 8位TH0 = (-20000)>>8;/右移8位,實(shí)際上是取高8位TR0=1;/允許T0開(kāi)始計(jì)數(shù)ET0=1;/允許T0計(jì)數(shù)溢出時(shí)產(chǎn)生中斷請(qǐng)求EA=1;/允許CPLP向應(yīng)中斷請(qǐng)求while( 1 )/永遠(yuǎn)為真,即死循環(huán)if( keyHit() != 0 )/如果隊(duì)列中有按鍵P2=Seg7Code keyGet();/從隊(duì)列中取出按鍵值,并顯示在數(shù)碼管上void timer0int( void ) interrupt 1/20ms ; T0的中斷號(hào)為1/方式1為軟件重載/右移8位,實(shí)際上是取局 static unsigned char sts=0;TH
49、0 = (-20000)>>8;8位/按鍵則轉(zhuǎn)入狀態(tài)1/假按錯(cuò),或干擾,回狀態(tài) 0/確實(shí)按鍵,鍵值入隊(duì)列,并轉(zhuǎn)狀態(tài)2/如果松鍵,則轉(zhuǎn)狀態(tài) 3/假松鍵,回狀態(tài)2/真松鍵,回狀態(tài)0,等待下一次按鍵過(guò)程TL0 = -20000;P1_0 = 1;/作為輸入引腳,必須先輸出高電平switch( sts )case 0: if( keyScan()!=0 ) sts=1; break;case 1:if( keyScan()=0 ) sts=0;else sts=2; keyPut( keyScan() ); ) break;case 2: if(keyScan()=0 ) sts=3; b
50、reak;case 3:if( keyScan()!=0 ) sts=2;else sts=0;第六節(jié):低頻頻率計(jì)實(shí)例目的:學(xué)時(shí)定時(shí)器、計(jì)數(shù)器、中斷應(yīng)用 說(shuō)明:選用24MHz的晶體,主頻可達(dá) 2MHz用T1產(chǎn)生100us的時(shí)標(biāo),T0作信號(hào)脈沖計(jì)數(shù)器。假設(shè)晶體頻 率沒(méi)有誤差,而且穩(wěn)定不變(實(shí)際上可達(dá)萬(wàn)分之一);被測(cè)信號(hào)是周期性矩形波(正負(fù)脈沖寬度都不能小于0.5us ),頻率小于1MHz大于1Hz。要求測(cè)量時(shí)標(biāo)1S,測(cè)量精度為0.1%。解:從測(cè)量精度要求來(lái)看,當(dāng)頻率超過(guò) 1KHz時(shí),可采用1S時(shí)標(biāo)內(nèi)計(jì)數(shù)信號(hào)脈沖個(gè)數(shù)來(lái)測(cè)量信號(hào)頻,而信 號(hào)頻率低于1KHz時(shí),可以通過(guò)測(cè)量信號(hào)的周期來(lái)求出信號(hào)頻率。兩
51、種方法自動(dòng)轉(zhuǎn)換。對(duì)于低于1KHz的信號(hào),信號(hào)周期最小為1m§也就是說(shuō)超過(guò)1000us ,而我們用的定時(shí)器計(jì)時(shí)脈沖周期 為0.5us ,如果定時(shí)多計(jì)或少計(jì)一個(gè)脈沖,誤差為1us,所以相對(duì)誤差為1us/1000us=0.1%。信號(hào)周期越大,即信號(hào)頻率越低,相對(duì)誤差就越小。從上面描述來(lái)看,當(dāng)信號(hào)頻率超過(guò)1KHz后,信號(hào)周期就少于1000us,顯然采用上面的測(cè)量方法,不能達(dá)到測(cè)量精度要求,這時(shí)我們采用1S單位時(shí)間計(jì)數(shù)信號(hào)的脈沖個(gè)數(shù),最少能計(jì)到1000個(gè)脈沖,由于信號(hào)頻率不超過(guò)1MHz而我們定時(shí)脈沖為 2MHz最差多計(jì)或少計(jì)一個(gè)信號(hào)脈沖,這樣相對(duì)誤差為1/1000,可見(jiàn)信號(hào)頻率越高,相對(duì)誤差越
52、小。信號(hào)除輸入到T1 (P3.5 )夕卜,還輸入到INT1 (P3.3 )。unsigned int us100;/對(duì)100us時(shí)間間隔單位計(jì)數(shù),即有多少個(gè)100us。unsigned char Second;unsigned int K64;/對(duì)64K單位計(jì)數(shù),即有多少個(gè) 64Kunsigned char oldT0;unsigned int oldus, oldK64, oldT1;unsigned long fcy;/存放頻率值,單位為 Hzbit HighLow=1;void InitialHigh( void ) (/1 :表示信號(hào)超過(guò)1KH乙0:表示信號(hào)低于1KHz。IE=0; IP=0; HighLo
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 代收美金合同范本
- 2025年度新型環(huán)保混凝土材料購(gòu)銷合同范本集錦
- 勞動(dòng)生產(chǎn)合同范例
- 喬木修剪合同范本
- 公司投資電影合同范例
- 個(gè)人外貿(mào)合同范例
- 2014家裝合同范例
- 信息資產(chǎn)安全合同范本
- 借用合同范例 英文
- 旅游業(yè)個(gè)性化旅游定制服務(wù)方案
- 2024年浙江省自然資源集團(tuán)有限公司招聘筆試參考題庫(kù)附帶答案詳解
- 酒店春節(jié)營(yíng)銷方案
- 營(yíng)銷管理方案中的定價(jià)策略與盈利模式
- 2024年西寧城市職業(yè)技術(shù)學(xué)院高職單招(英語(yǔ)/數(shù)學(xué)/語(yǔ)文)筆試歷年參考題庫(kù)含答案解析
- 2024年臨沂市高三一模(學(xué)業(yè)水平等級(jí)考試模擬試題)物理試卷
- 廣州獵德大橋三維曲面塔清水混凝土施工技術(shù)
- 我國(guó)糖尿病視網(wǎng)膜病變臨床診療指南2022解讀
- 高級(jí)茶藝師技能鑒定(協(xié)會(huì)版)備考題庫(kù)-下(多選、判斷題匯總)
- 特種設(shè)備作業(yè)人員體檢表(叉車)
- c30混凝土路面施工方案
- 加強(qiáng)師德師風(fēng)建設(shè)學(xué)校師德師風(fēng)警示教育講座培訓(xùn)課件
評(píng)論
0/150
提交評(píng)論