键盘译码程序是开发项目中最常用到的程序,它的好坏,直接影响着整个程序!现在介绍一个使用非常广泛的Keil C51键盘译码程序。 在主程序中不断调用KeyBord(),可以不停地扫描键盘! 在功能子程序中调用:unsigned charJB_KeyData(),得到键值 #define TK 8 //主程序执行时间8ms #define Timer20ms (30/TK) //延时时间20ms #define Timer2S (1200/TK) //延时时间2S #define Timer100ms (1000/TK) //延时时间100ms #define Port P2 //键盘口 //**************************** KEY KeyDat; //定义数据结构 //--------------------------- //5个开关占用的IO脚 //--------------------------- sbit ko=Port^0; sbit ka=Port^1; sbit kb=Port^2; sbit kc=Port^3; sbit kd=Port^4; /*************************** 根据硬件电路不同,只修改这段程序即可!!! ***************************/ 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++; } } /*************************** 延时去抖动 ***************************/ 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;//定义标志 }else{ if(0==-KeyDat.KeyDog){ //3秒延时到 KeyDat.KeyDog=Timer100ms; KeyDat.KeyPower++; } } } /*************************** 连击是否松开 ***************************/ void KeyOff2(void) { if(ReadKey()!=0){ if (0==--KeyDat.KeyDog){ KeyDat.KeyData |=DubClick | HaveKey; //连击标志 KeyDat.KeyDog=Timer100ms; /*************************** // BeepPower=1;//发送蜂鸣器短鸣命令 ***************************/ } }else{ KeyDat.KeyData=0; //?|=HaveKey;//一次按键 KeyDat.KeyPower=0; } } /*************************** 函数指针定义 ***************************/ code void(code *SubKey[])()={ GetKey,KeyDog,KeyOff1,KeyOff2 }; /*************************** 键处理程序用户在主程序只需不断调用它! ***************************/ void KeyBord(void){ (*SubKey[KeyDat.KeyPower])(); /*************************** 用户在功能函数中调用,返回键处理后清除键值 ***************************/ 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;//延时 unsigned char KeyData;//键值 }KEY;
|