單片機基本知識和基礎應用課程[1]參考模板_第1頁
單片機基本知識和基礎應用課程[1]參考模板_第2頁
單片機基本知識和基礎應用課程[1]參考模板_第3頁
單片機基本知識和基礎應用課程[1]參考模板_第4頁
單片機基本知識和基礎應用課程[1]參考模板_第5頁
已閱讀5頁,還剩37頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、如有問題請發(fā)送E-mail到 zhaojian。單片機基礎知識單片機的外部結(jié)構(gòu):1、 DIP40雙列直插;2、 P0,P1,P2,P3四個8位準雙向I/O引腳;(作為I/O輸入時,要先輸出高電平)3、 電源VCC(PIN40)和地線GND(PIN20);4、 高電平復位RESET(PIN9);(10uF電容接VCC與RESET,即可實現(xiàn)上電復位)5、 內(nèi)置振蕩電路,外部只要接晶體至X1(PIN18)和X0(PIN19);(頻率為主頻的12倍)6、 程序配置EA(PIN31)接高電平VCC;(運行單片機內(nèi)部ROM中的程序)7、 P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1單片

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

3、數(shù)賦給一個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)體,也就是;第一章 單片機最小應用系統(tǒng):單片機最小系統(tǒng)的硬件原理接線圖:1、 接電源:VCC(PIN40)、GND(PIN20)。加接退耦電容0.1uF2、 接晶體:X1(PIN18)、X2(PIN

4、19)。注意標出晶體頻率(選用12MHz),還有輔助電容30pF3、 接復位:RES(PIN9)。接上電復位電路,以及手動復位電路,分析復位工作原理4、 接配置:EA(PIN31)。說明原因。具體接法如下圖所示:1 / 42第二章 基本I/O口的應用。例1:用P1口輸出一倍頻方波。#include <reg52.h> /reg52.h為包含51資源的庫文件void main ( void )while (1=1)+P1; /使P1口加一完成一倍頻方波,不同的口輸出不同,高位變化慢,底位快注意:P0的每個引腳要輸出高電平時,必須外接上拉電阻(如4K7)至VCC電源。例2:用P1口輸出

5、一倍頻方波,要求能用萬用表測出方波。其實,只需要在上面的程序中添加延時程序即可。#include <reg52.h>void main ( void )unsigned int i,j;while (1)+P1;for (i=0;i<1000;i+) for(j=0;j<1000;j+); /該循環(huán)是一個大概的延時,具體時間要看匯編語言的指令才能判斷。例3:要求從P1口輸出一方波,要求P1.7變化的最快,P1.0變化的最慢。#include <reg52.h>void main ( void )unsigned char m,n; /定義兩個中間變量完成交換

6、過程unsigned int i,j;while (1)n = 0;+m;n|=(m<<7)&0x80; /將第0位的值送至第7位n|=(m<<5)&0x40; /將第1位的值送至第6位n|=(m<<3)&0x20; /將第2位的值送至第5位 n|=(m<<1)&0x10; /將第3位的值送至第4位 n|=(m>>1)&0x08; /將第4位的值送至第3位 n|=(m>>3)&0x04; /將第5位的值送至第2位 n|=(m>>5)&0x02; /將第6位

7、的值送至第1位 n|=(m>>7)&0x01; /將第7位的值送至第0位 P1 = n;for(i=0;i<1000;i+)for(j=0;j<1000;j+);注意:一個字節(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。第三章 顯示驅(qū)動數(shù)碼管的接法和驅(qū)動原理一支七段數(shù)碼管實際由8個發(fā)光二極管構(gòu)成,其中7個

8、組形構(gòu)成數(shù)字8的七段筆畫,所以稱為七段數(shù)碼管,而余下的1個發(fā)光二極管作為小數(shù)點。作為習慣,分別給8個發(fā)光二極管標上記號:a,b,c,d,e,f,g,h。對應8的頂上一畫,按順時針方向排,中間一畫為g,小數(shù)點為h。我們通常又將各二極與一個字節(jié)的8位對應,a(D0),b(D1),c(D2),d(D3),e(D4),f(D5),g(D6),h(D7),相應8個發(fā)光二極管正好與單片機一個端口Pn的8個引腳連接,這樣單片機就可以通過引腳輸出高低電平控制8個發(fā)光二極的亮與滅,從而顯示各種數(shù)字和符號;對應字節(jié),引腳接法為:a(Pn.0),b(Pn.1),c(Pn.2),d(Pn.3),e(Pn.4),f(P

9、n.5),g(Pn.6),h(Pn.7)。如果將8個發(fā)光二極管的負極(陰極)內(nèi)接在一起,作為數(shù)碼管的一個引腳,這種數(shù)碼管則被稱為共陰數(shù)碼管,共同的引腳則稱為共陰極,8個正極則為段極。否則,如果是將正極(陽極)內(nèi)接在一起引出的,則稱為共陽數(shù)碼管,共同的引腳則稱為共陽極,8個負極則為段極。以單支共陰數(shù)碼管為例,可將段極接到某端口Pn,共陰極接GND,則可編寫出對應十六進制碼的七段碼表字節(jié)數(shù)據(jù)如下圖:動態(tài)顯示的電路連接如下圖所示:P1口下面,我們編程在數(shù)碼管上顯示出“1 2 3 4”。程序如下:#include <reg52.h>Code unsigned char Seg7Code16

10、=/用十六進數(shù)作為數(shù)組下標,可直接取得對應的七段編碼字節(jié)/ 0 1 2 3 4 5 6 7 8 9 A b C d E F0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71;void main ( void )unsigned int i;while (1)P2 |= 0x0f; /消隱,讓數(shù)碼管開始處于不亮的狀態(tài) P0 = LedCode1; /將“1”的代碼送出P2 &= 0xfe; /選中第一個數(shù)碼管for(i=0;i<1000;i+);

11、P2 |= 0x0f; P0 = LedCode2;P2 &= 0xfd; for(i=0;i<1000;i+);P2 |= 0x0f; P0 = LedCode3;P2 &= 0xfb; for(i=0;i<1000;i+);P2 |= 0x0f; P0 = LedCode4;P2 &= 0xf7; for(i=0;i<1000;i+);關于DRIVER編寫DRIVER的目的是讓程序能適應更多的場合,讓我們的使用更加方便,可以把一些自己編過的有用的程序做成DRIVER便于自己以后的使用。下面介紹顯示的驅(qū)動程序:首先,定義一個頭文檔 <LedDr

12、iver.H>,描述可用函數(shù),如下:#ifndef _ LedDriver_H _/防止重復引用該文檔,如果沒有定義過符號 _KEY_H_,則編譯下面語句#define _ LedDriver_H _/只要引用過一次,即 #include <key.h>,則定義符號 _KEY_H_void LedPrint ( unsigned char Dat ) /數(shù)據(jù)緩沖區(qū)間,完成移位功能void LedWork ( void ) /送數(shù)到顯示數(shù)碼管#endif然后,定義函數(shù)體文檔 LedDriver.C,如下:#include <reg52.h>#include “Led

13、Driver.h”Code unsigned char LedCode16=/Code是表示這個數(shù)組的存儲空間0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71;unsigned char DisBuf4;void LedPrint (unsigned char Dat)DisBuf0 = DisBuf1; /每次用后一個數(shù)沖掉前一個數(shù),便于擴展顯示位數(shù)DisBuf1 = DisBuf2;DisBuf2 = DisBuf3;DisBuf3 = Dat;voi

14、d LedWork ( void )static unsigned char i = 0; /static表示靜態(tài)變量,指變量的賦值只在第一次定義的時候賦P2 |= 0x0f;P0 = LedCodeDisBufi;Switch( i ) /選擇數(shù)據(jù)送到哪個管子case 0: P2_0 = 0; break;case 1: P2_1 = 0; break;case 2: P2_2 = 0; break;case 3: P2_3 = 0; break;if (+i>=4) i = 0; /判斷四位數(shù)是否都已經(jīng)送完for (m=0;m<1000;m+); /延時這樣DRIVER的程序就

15、編好了,我們以后用的時候直接調(diào)用函數(shù)就可以了。主程序可以編寫如下:#include <reg52.h>#include “LedDriver.h”void mian ( void )LedPrint( 1 ); /調(diào)用函數(shù),把想顯示的數(shù)據(jù)送如緩存LedPrint( 2 );LedPrint( 3 );LedPrint( 4 );While( 1 )LedWork( );下面介紹一個例子供大家參考。顯示“12345678”P1端口接8聯(lián)共陰數(shù)碼管SLED8的段極:P1.7接段h,,P1.0接段aP2端口接8聯(lián)共陰數(shù)碼管SLED8的段極:P2.7接左邊的共陰極,P2.0接右邊的共陰極方

16、案說明:晶振頻率fosc=12MHz,數(shù)碼管采用動態(tài)刷新方式顯示,在1ms定時斷服務程序中實現(xiàn)#include <reg52.h>unsigned char DisBuf8; /全局顯示緩沖區(qū),DisBuf0對應右SLED,DisBuf7對應左SLED,void DisplayBrush( void )code unsigned char cathode8=0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f;/陰極控制碼code unsigned char Seg7Code16=/用十六進數(shù)作為數(shù)組下標,可直接取得對應的七段編碼字節(jié)0x3f,0x06,0

17、x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;static unsigned char i=0; / (0i7) 循環(huán)刷新顯示,由于是靜態(tài)變量,此賦值只做一次。P2 = 0xff;/顯示消隱,以免下一段碼值顯示在前一支SLEDP1 = Seg7Code DisBufi ;/從顯示緩沖區(qū)取出原始數(shù)據(jù),查表變?yōu)槠叨未a后送出顯示P2 = cathode i ;/將對應陰極置低,顯示if( +i >= 8 ) i=0;/指向下一個數(shù)碼管和相應數(shù)據(jù)void Timer0IntRoute( void ) in

18、terrupt 1TL0 = -1000;/由于TL0只有8bits,所以將(-1000)低8位賦給TL0TH0 = (-1000)>>8;/?。?1000)的高8位賦給TH0,重新定時1msDisplayBrush();void Timer0Init( void )TMOD=(TMOD & 0xf0) | 0x01;/初始化,定時器T0,工作方式1TL0 = -1000;/定時1msTH0 = (-1000)>>8;TR0 = 1;/允許T0開始計數(shù)ET0 = 1;/允許T0計數(shù)溢出時產(chǎn)生中斷請求void Display( unsigned char inde

19、x, unsigned char dataValue ) DisBuf index = dataValue;void main( void )unsigned char i;for( i=0; i<8; i+ ) Display(i, 8-i);區(qū)qhkode DisBufi ;/; f7,0xfd,0xfb,0xfe; /DisBuf0為右,DisBuf0為左Timer0Init();EA = 1;/允許CPU響應中斷請求While(1);第四章 鍵盤驅(qū)動單片機I/O口作為輸入的前提是必須首先輸出一個高電平。 char Kbhit ( void )P1.0 P1_0 = 1; if (

20、P1_9 = = 0 ) return ( 1 ); else return ( 0 );)下面我們對上面的程序作個改進:char Kbhit ( void )P1 = 0xff;if (P10xff) != 0) return ( 1 );一般來說,按鍵的時候會有抖動,我們可以用加延時的辦法來去除抖動。即:P1 =0xff;if (P10xff )!= 0) 延時20ms;if (P10xff) !=0) return (1);4X4按鍵。由P1端口的高4位和低4位構(gòu)成4X4的矩陣鍵盤,本程序只認為單鍵操作為合法,同時按多鍵時無效。P1.0(0xE)P1.1(0xD)P1.2(0xB)P1.

21、3(0x7)P1.4(E)P1.5(D)P1.6(B)P1.7(7)FEDCBA9876A543210取鍵值的程序如下:unsigned char getch ( void )unsigned char X,Y,Z;P1 = 0xf0;X = P1;P1 = 0x0f;Y = P1; Z =X | Y;switch ( Z )case 0xee: return ( 0 );case 0xde: return ( 1 );case 0xbe: return ( 2 );case 0x7e: return ( 3 );case 0xed: return ( 4 );case 0xdd: retur

22、n ( 5 );case 0xbd: return ( 6 );case 0x7d: return ( 7 );case 0xeb: return ( 8 );case 0xdb: return ( 9 );case 0xbb: return ( 10 );case 0x7b: return ( 11 );case 0xe7: return ( 12 );case 0xd7: return ( 13 );case 0xb7: return ( 14 );case 0x77: return ( 15 );判斷有無鍵按下的程序:char Kbhit ( void )P1 = 0xf0;if (P1

23、 = = 0xf0) return ( 0 );else return ( 1 );下面是鍵盤的Driver程序:首先我們還是來寫KeyDriver.h這個程序:#ifndef _KeyDriver_h_#define _KeyDriver_h_char Khbit ( void );char Getch ( void );#endif接著,我們來寫KeyDriver.c程序#include <reg52.h>#include “KeyDriver.h”char Kbhit ( void )P1 = 0xf0;if (P1 = = 0xf0) return ( 0 );else r

24、eturn ( 1 );unsigned char getch ( void )unsigned char X,Y,Z;P1 = 0xf0;X = P1;P1 = 0x0f;Y = P1; Z =X | Y;switch ( Z )case 0xee: return ( 0 );case 0xde: return ( 1 );case 0xbe: return ( 2 );case 0x7e: return ( 3 );case 0xed: return ( 4 );case 0xdd: return ( 5 );case 0xbd: return ( 6 );case 0x7d: retur

25、n ( 7 );case 0xeb: return ( 8 );case 0xdb: return ( 9 );case 0xbb: return ( 10 );case 0x7b: return ( 11 );case 0xe7: return ( 12 );case 0xd7: return ( 13 );case 0xb7: return ( 14 );case 0x77: return ( 15 );按鍵顯示程序如下:#include < reg52.h >#include “LedDriver.h”#include “KeyDriver.h”void main ( voi

26、d )unsigned char i; for (i=1;i<5;i+) LedPrint ( i );while ( 1 )if (Kbhit( ) LedPrint ( Getch( );LedWork ( );下面是另一個鍵盤值的算法,供大家參考。P1.0(0xE)P1.1(0xD)P1.2(0xB)P1.3(0x7)P1.4(E)P1.5(D)P1.6(B)P1.7(7)FEDCBA9876543210定義一個頭文檔 <KEY.H>,描述可用函數(shù),如下:#ifndef _KEY_H_/防止重復引用該文檔,如果沒有定義過符號 _KEY_H_,則編譯下面語句#define

27、 _KEY_H_/只要引用過一次,即 #include <key.h>,則定義符號 _KEY_H_unsigned char keyHit( void );/如果按鍵,則返回非,否則返回unsigned char keyGet( void );/讀取按鍵值,如果沒有按鍵則等待到按鍵為止void keyPut( unsigned char ucKeyVal );/保存按鍵值ucKeyVal到按鍵緩沖隊列末void keyBack( unsigned char ucKeyVal );/退回鍵值ucKeyVal到按鍵緩沖隊列首#endif定義函數(shù)體文檔 KEY.C,如下:include

28、“key.h”#define KeyBufSize16/定義按鍵緩沖隊列字節(jié)數(shù)unsigned char KeyBuf KeyBufSize ;/定義一個無符號字符數(shù)組作為按鍵緩沖隊列。該隊列為先進/先出,循環(huán)存取,下標從到 KeyBufSize-1unsigned char KeyBufWp=0;/作為數(shù)組下標變量,記錄存入位置unsigned char KeyBufRp=0;/作為數(shù)組下標變量,記錄讀出位置/如果存入位置與讀出位置相同,則表明隊列中無按鍵數(shù)據(jù)unsigned char keyHit( void )if( KeyBufWp = KeyBufRp ) return( 0 );

29、else return( 1 ); unsigned char keyGet( void )unsigned char retVal;/暫存讀出鍵值while( keyHit()=0 );/等待按鍵,因為函數(shù)keyHit()的返回值為 0 表示無按鍵retVal = KeyBuf KeyBufRp ;/從數(shù)組中讀出鍵值if( +KeyBufRp >= KeyBufSize ) KeyBufRp=0;/讀位置加,超出隊列則循環(huán)回初始位置return( retVal );void keyPut( unsigned char ucKeyVal )KeyBuf KeyBufWp = ucKeyV

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

31、BufRp=KeyBufSize-1; KeyBuf KeyBufRp = ucKeyVal;/回存鍵值#include <at89x52.h>#include “KEY.H”unsigned char keyScan( void )/返回0表示無按鍵,或無效按鍵,其它值為按鍵編碼值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

32、, 0 ; unsigned char x, y, retVal;P1=0x0f;/低四位輸入,高四位輸出0x=P1&0x0f;/P1輸入后,清高四位,作為X值P1=0xf0;/高四位輸入,低四位輸出0y=(P1 >> 4) & 0x0f;/P1輸入后移位到低四位,并清高四位,作為Y值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

33、=0xb,Y=0xd,算得retVal=11,所以返回函數(shù)值7。void main( void )TMOD = (TMOD & 0xf0 ) | 0x01;/不改變T1的工作方式,T0為定時器方式1TL0 = -20000;/計數(shù)周期為20000個主頻脈,自動取低8位TH0 = (-20000)>>8;/右移8位,實際上是取高8位TR0=1;/允許T0開始計數(shù)ET0=1;/允許T0計數(shù)溢出時產(chǎn)生中斷請求EA=1;/允許CPU響應中斷請求while( 1 )/永遠為真,即死循環(huán)if( keyHit() != 0 )/如果隊列中有按鍵P2=Seg7Code keyGet() ;

34、/從隊列中取出按鍵值,并顯示在數(shù)碼管上void timer0int( void ) interrupt 1/20ms;T0的中斷號為1static unsigned char sts=0;TL0 = -20000;/方式1為軟件重載TH0 = (-20000)>>8;/右移8位,實際上是取高8位P1_0 = 1;/作為輸入引腳,必須先輸出高電平switch( sts )case 0: if( keyScan()!=0 ) sts=1; break;/按鍵則轉(zhuǎn)入狀態(tài)1case 1:if( keyScan()=0 ) sts=0;/假按錯,或干擾,回狀態(tài)0else sts=2; key

35、Put( keyScan() ); /確實按鍵,鍵值入隊列,并轉(zhuǎn)狀態(tài)2break;case 2: if(keyScan()=0 ) sts=3; break;/如果松鍵,則轉(zhuǎn)狀態(tài)3case 3:if( keyScan()!=0 ) sts=2;/假松鍵,回狀態(tài)2else sts=0;/真松鍵,回狀態(tài)0,等待下一次按鍵過程第五章 中斷系統(tǒng)應用對于51系列單片機的中斷資源在本課件中就不再多加描述,同學們可以參考書上的一些資料,主要在這里是介紹它的應用。序號 中斷源 中斷控制位(允許否) 優(yōu)先控制位 中斷狀態(tài) 其他 0 X0EX0PX0 IE0 INT0 1 Timer0 ET0PT0 TF0 T0

36、 2 X1 EX1PX1 IE1 INT1 3 Timer1 ET1 PT1 TF1 T1 4 UART ES PS RXD/TXD RI/TI 5 Timer2 ET2 PT2 TF2 T2 EA完成以下程序設計(初始化):要求:1、將串口中斷的級別設置為最高; 2、INT0工作于邊沿模式,INT1工作于電平模式,這兩個中斷都是從外部輸入; 3、允許T1定時器中斷。#include <reg52.h>void main ( void )EA = 0;PS = 1; PT1 = 0; PT0 = 0; PX0 = 0; PX1 = 0; /設置串口的中斷級別最高INT1 = 1;

37、INT0 = 1; /設置外部輸入中斷IT0 = 1; IT1 = 0; /設置INT0工作于邊沿模式,INT1工作于電平模式ET1 = 1; /允許定時器1中斷 EX0 = 1; EX1 = 1; /允許外部中斷0、1工作ES = 1; /允許串口中斷EA = 1;/開中斷while ( 1 );下面的程序為中斷的具體應用,主要是針對T2定時器的中斷。#include <REG52.h>void main( void )EA = 0; /disable interrupt for systemC_T2 = 0;/timeCP_RL2 = 0;/ReloadRCAP2L = -10

38、00;/low 8 bitsRCAP2H = (-1000)>>8;/high 8 bitsTL2 = RCAP2L;/first load to T2TH2= RCAP2H;TR2 = 1; /start countET2 = 1;/enable Timer2 interruptEA= 1;/open interrupt for systemwhile( 1 );void Timer2Int( void ) interrupt 5TF2 = 0;P1 = 0xff;下面的程序是將按鍵和顯示放在中斷服務程序中進行處理。程序內(nèi)容為上課時的例子test2。clock.h文件編寫如下:#

39、ifndef _clock_h_#define _clock_h_#define SysClock3686400struct sClockunsigned char flag;unsigned long second;/232 seconds for 136 yearsunsigned int ms;void ClockOpen( void );struct sClock * ClockGet( void );/void ClockSet( struct sClock *ptr );void ClockCall( void );extern struct sClock gClock;#endi

40、fclock.c文件編寫如下:#include <reg52.h>#include "clock.h"#include "LedDriver.h"#include "KeyDriver.h"void ClockCall_ms( void )LedTimeCall();KeyTimeCall();void ClockOpen( void )/初始化Timer2產(chǎn)生1ms定時中斷gClock.ms=0;gClock.second=0;CP_RL2 = 0;/重載模式C_T2 = 0;/定時器方式RCAP2H = (-(SysC

41、lock/1000) >> 8;/重載值高8位RCAP2L = (-(SysClock/1000) & 0x00ff;/重載值低8位TR2= 1;/允許定時計數(shù)ET2 = 1;/允許Timer2中斷 void T2int( void ) interrupt 5TF2 = 0;/clear interrupt status ClockCall_ms();KeyDriver.h文件編寫如下:#ifndef _KeyDriver_H_#define _KeyDriver_H_#defineKeyBufSize 4char kbhit( void );char getch( voi

42、d );void KeyBufIn( char dat );void KeyTimeCall( void );#endifKeyDriver.c文件編寫如下:#include <reg52.h>#include "KeyDriver.h"unsigned char KeyBufWp=0;unsigned char KeyBufRp=0;unsigned char KeyBufKeyBufSize;char kbhit( void )return( KeyBufWp - KeyBufRp ); char getch( void )char ret;ret = Ke

43、yBuf KeyBufRp ;if( +KeyBufRp >= KeyBufSize ) KeyBufRp=0;return( ret );void KeyBufIn( char dat )KeyBuf KeyBufWp = dat;if( +KeyBufWp >= KeyBufSize ) KeyBufWp=0;void KeyTimeCall( void )code char KeyCode=/* 0 1 2 3 4 5 6 7 8 9 AB C DE F */ 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0

44、xff, 0xff,0xff,0xff,0xff,/0 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, /10xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, /2 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, /30xff,0xff,0xf

45、f,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, /4 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, /5 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, /6 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0x0F, 0xff,0xff,

46、0xff,0x0B, 0xff,0x07,0x03,0xff, /70xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, /8 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, /9 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, /A 0xff,

47、0xff,0xff,0xff, 0xff,0xff,0xff,0x0E, 0xff,0xff,0xff,0x0A, 0xff,0x06,0x02,0xff, /B 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, /C 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0x0D, 0xff,0xff,0xff,0x09, 0xff,0x05,0x01,0xff, /D 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0x0C, 0x

48、ff,0xff,0xff,0x08, 0xff,0x04,0x00,0xff, /E 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff /F ;unsigned char KeyScan;static unsigned char KeyScanCode=0;static unsigned char sts=0;static unsigned char ms=20;if( -ms ) return;ms=20;P1=0x0f;KeyScan=P1;P1=0xf0;KeyScan|=P1;switch( sts )case 0:if( KeyScan != 0xff )/可能有按鍵 sts=1; KeyScanCode=KeyScan; break;case 1:if( KeyScanCode = KeyScan )/去抖后確為鍵按下sts = 2;KeyBufIn( KeyCode KeyScan );/返回鍵值else/否則認為是干擾,重新檢測sts = 0;break;case 2:if( KeyScanCode != KeyScan )/檢測松開按鍵if( KeySca

溫馨提示

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

評論

0/150

提交評論