键盘译码程序是开发项目中最常用到的程序,它的好坏,直接影响着整个程序!现在介绍一个使用非常广泛的Keil C51键盘译码程序。
在主程序中不断调用KeyBord(),可以不停地扫描键盘!
在功能子程序中调用:unsigned charJB_KeyData(),得到键值
#define TK8//主程序执行时间8ms #define Timer20ms(30/TK)//延时时间20ms #define Timer2S(1200/TK) //延时时间2S #define Timer100ms(1000/TK)//延时时间100ms #define Port P2 //键盘口 //**************************** KEYKeyDat;//定义数据结构 //--------------------------- //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;