鍵盤譯碼程序是開發(fā)項(xiàng)目中最常用到的程序,它的好壞,直接影響著整個(gè)程序!現(xiàn)在介紹一個(gè)使用非常廣泛的Keil C51鍵盤譯碼程序。
在主程序中不斷調(diào)用KeyBord(),可以不停地掃描鍵盤!
在功能子程序中調(diào)用:unsigned charJB_KeyData(),得到鍵值
#define TK 8 //主程序執(zhí)行時(shí)間8ms
#define Timer20ms (30/TK) //延時(shí)時(shí)間20ms
#define Timer2S (1200/TK) //延時(shí)時(shí)間2S
#define Timer100ms (1000/TK) //延時(shí)時(shí)間100ms
#define Port P2 //鍵盤口
//****************************
KEY KeyDat; //定義數(shù)據(jù)結(jié)構(gòu)
//---------------------------
//5個(gè)開關(guān)占用的IO腳
//---------------------------
sbit ko=Port^0;
sbit ka=Port^1;
sbit kb=Port^2;
sbit kc=Port^3;
sbit kd=Port^4;
/***************************
根據(jù)硬件電路不同,只修改這段程序即可!!!
***************************/
unsigned char ReadKey(void){
ko=0;
if(!ka) return 2;//Ka
if(!kb) return 3;//Kb
if(!kc) return 4;//Kc
if(!kd) return 5;//Kd
return 0;
}
/***************************
判別是否有建
***************************/
void GetKey(void){
if(ReadKey()!=0){
KeyDat.KeyDog=Timer20ms;
KeyDat.KeyPower++;
}
}
/***************************
延時(shí)去抖動(dòng)
***************************/
void KeyDog(void){
if(0==-KeyDat.KeyDog){
KeyDat.KeyData=ReadKey(); //讀鍵盤
if(KeyDat.KeyData!=0){
KeyDat.KeyPower++;
KeyDat.KeyDog=Timer3S;
/***************************
// BeepPower=1;//蜂鳴器短鳴
***************************/
}else{
KeyDat.KeyPower=0:
KeyDat.KeyData=0; //返回
}
}
}
/***************************
判別是否松開
***************************/
void KeyOff1(void){
if(ReadKey0==0){ //松開按鍵
KeyDat.KeyPower=0;
KeyDat.KeyData |=HaveKey;//定義標(biāo)志
}else{
if(0==-KeyDat.KeyDog){ //3秒延時(shí)到
KeyDat.KeyDog=Timer100ms;
KeyDat.KeyPower++;
}
}
}
/***************************
連擊是否松開
***************************/
void KeyOff2(void)
{
if(ReadKey()!=0){
if (0==--KeyDat.KeyDog){
KeyDat.KeyData |=DubClick | HaveKey; //連擊標(biāo)志
KeyDat.KeyDog=Timer100ms;
/***************************
// BeepPower=1;//發(fā)送蜂鳴器短鳴命令
***************************/
}
}else{
KeyDat.KeyData=0; //?|=HaveKey;//一次按鍵
KeyDat.KeyPower=0;
}
}
/***************************
函數(shù)指針定義
***************************/
code void(code *SubKey[])()={
GetKey,KeyDog,KeyOff1,KeyOff2
};
/***************************
鍵處理程序用戶在主程序只需不斷調(diào)用它!
***************************/
void KeyBord(void){
(*SubKey[KeyDat.KeyPower])();
/***************************
用戶在功能函數(shù)中調(diào)用,返回鍵處理后清除鍵值
***************************/
unsigned char JB_KeyData(void){
unsigned char i=0;
if (KeyDat.KeyData>DubClick){
i=KeyDat.KeyData;
KeyDat.KeyData=0;
}
return i;
}
以下是頭文件:
/***************************
鍵盤的鍵值定義
***************************/
#define DubClick 0x40 //連擊
#define HaveKey 0x80 //有鍵
#define SeeKey (0x01|HaveKey)
#define SetKey (0x02|HaveKey)
#define RRKey (0x03|HaveKey)
#define UpKey (0x04|HaveKey)
#define RetKey (0x05|HaveKey)
#define RLKey (0x02|HaveKey)
//#define UseKey (0x06|HaveKey)
#define SeeKey_Dub (SeeKey | DubClick | HaveKey)
#define SetKey_Dub (SetKey | DubClick | HaveKey)//雙擊
#define RRKey_Dub (RRKey | DubClick | HaveKey)
#define UpKey_Dub (UpKey | DubClick | HaveKey)
#define RetKey_Dub (RetKey | DubClick | HaveKey)
//#define UseKey_Dub (UseKey | DubClick | HaveKey)
//--------------------------
typedef struct{
unsigned char KeyPower; //命令字
unsigned int KeyDog;//延時(shí)
unsigned char KeyData;//鍵值
}KEY;