來源:mcu99.com 作者:李佰戰(zhàn) /********************************************************************************** KeyBoard Encode Program This Program can encode press_key up to 128 and it can deal KB_DBClick Message This is just a test proram and only use 2 key.If More Key need to Encode ,please modify the function:KBKeyPress() This Porgram use Message_Driver method,the KB_Msg is used to record what KB_Msg has occured. The meaning of 'SysKBMsg' is list as following. Program Design:LiBaizhan Ver:1.10 Date:2003-3-16 ************************************************************************************/ #i nclude <reg51.h> #i nclude <intrins.h> sbit Key1 = P1^0; sbit Key2 = P1^1; /* Some System Var Pre_Definition Crystal Frequence is 11.0592MHz */ #define TIME_2MS 0X74 #define TIME_20MS 0X043B #define KB_INTERNAL 3 /*Key DBClk Detection Internal */ /* SysKBMsg define Keyboard Message,it include Single_Click or Double_Click It's bit6~bit0 record key_encode and bit 7 record DBClk(1) or SglClk(0) It can record and encode up to 127(2^7-1) keys No key is press when it is 0 This method did not deal key such as Ctrl_Key or Alt_Key or Shift_Key...etc. */ /*_________________________________________________*/ data unsigned char SysKBMsg=0; /*| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |*/ /*| D/S | KB6 | KB5 | KB4 | KB3 | KB2 | KB1 | KB0 |*/ data unsigned char KBCounter=0; bit KBCounterStart=0; bit KBCounterStop=0; /*if KeyBoard counter stop then this bit is 1*/ bit KBCounterFlag=0; /*Current Counter is used by KeyBoard*/ void TimerInt0(void) interrupt 1 /*timer 0 interrupt use to record how long key is press*/ { TR0=0; if(KBCounterFlag) /*Current Counter is used by KeyBoard*/ { if(KBCounter<KB_INTERNAL) /*if DBClk Detection is not finish then detect continue*/ { KBCounter++; TR0=1; } else { KBCounter=0; /*DBClk Detection is finish*/ KBCounterStop=1; } } } void DelayMS(unsigned int dltime); void Init51(void); unsigned char KBKeyPress(void); /*only return what key is press*/ void KBKeyEncode(void); /*encode which key is pressed and DBClk or SglClk*/ void KBStartTimer(unsigned char CntH,unsigned char CntL); /*load counter initial value and start timer*/ void KBStopTimer(void); void KBDealPressKey(void); /*deal key_press message*/
void main(void) { Init51(); while(1) { KBKeyEncode(); /*recored what KeyBoard Msg occure:which key is press and single clk or db clk*/ KBDealPressKey(); } } /* Delay Time is :(20+17*dl_time)*12/CrystalFrequence(us) */ void DelayMS(unsigned int dltime) { unsigned int i; for(i=0;i<dltime;i++); } void Init51(void) { SCON = 0x50; /* mode 1: 8-bit UART, enable receiver */ TMOD = 0x21; /* timer 1 mode 2: 8-Bit reload */ /* timer 0 mode 1: 16-bit Timer */ TH1 = BAUD_4800; /* reload value 9600 baud */ TR1 = 1; /* timer 1 run */ IE = 0X12; /* enable Serial INT,Timer0 INT */ ES = 0; /* disable Serial INT*/ EA = 1; /* Open INT Ctrl */ } void KBKeyEncode(void) { data unsigned char CurrPress=0,LastPress=0; if((LastPress=KBKeyPress())!=0) /*if some key is press then start encode*/ { KBStartTimer(0,0); /*some key is press then start DBClk Detection Counter*/ SysKBMsg=LastPress; /*record the key that is pressed this time*/ while(!KBCounterStop) { if((CurrPress=KBKeyPress())!=0X0) /*if some key is pressed during DBClk Detection then jump out to see wether DBclk is occured*/ break; } if((KBCounterStop==0)&&(LastPress==CurrPress)) /*this key DBClk occured*/ SysKBMsg|=0X80; KBStopTimer(); } } unsigned char KBKeyPress(void) { data unsigned char KeyPress=0; if((P1&0X03)!=0X03) { DelayMS(TIME_20MS); if((KeyPress=(P1&0X03))!=0X03) /*some key is press*/ { if(KBCounterStart) TR0=0; while((P1&0X03)!=0X03); /*wait until key is free*/ DelayMS(TIME_20MS); if(KBCounterStart) TR0=1; } else /*Key is not real press*/ { KeyPress=0; } } return KeyPress; } void KBStartTimer(unsigned char CntH,unsigned char CntL) { TR0=0; TH0=CntH; TR0=1; /*Start Counter*/ TL0=CntL; KBCounterFlag=1; /*this counter is used by KeyBoard*/ KBCounterStart=1; KBCounterStop=0; } void KBStopTimer(void) { TR0=0; TH0=0; TL0=0; KBCounter=0; KBCounterFlag=0; KBCounterStart=0; } void KBDealPressKey(void) { data unsigned char tmp=0; switch(SysKBMsg) /*here is just a test program,test to deal Sgl_Clk and DB_Clk Msg*/ { case 0X01: tmp=0X01;break; case 0X02: tmp=0X02;break; case 0X81: tmp=0X81;break; case 0X82: tmp=0X82;break; default : break; } SysKBMsg=0; /*this key msg has been done*/
|