键盘扫描方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
键盘扫描方法
传统的键盘扫描方法如图1所示,该方法虽然被广泛应用于很多场合,但有一个不足的地方,如果按键一直没有释放,或者按键坏了,一直处于闭合状态,则程序一直处于检测按键是否释放,系统将无法运行。
只要对其稍加改进,就可以避免产生这个问题。
假设键盘接口电路采用独立式键盘接口,所有按键公共端接地,而且没有按键按下时IO口为高电平。
当按键没有按下时,IO口为高电平;当按键按下时,IO口为低电平;当按键释放时,IO口为高电平。
一个完整的按键过程是——按键未按下,按键按下,按键释放,而对应的IO口的电平变化为——高电平,低电平,高电平。
所以,可以通过判断IO口电平变化的变化顺序是否满足高电平→低电平→高电平,来判断是否有按键按下,而对于其它的电平变化顺序都是无效的。
那么该如何实现呢?在键盘扫描过程中,如果IO口为高电平,则需要判断是由于未按键,还是按键按下后释放引起的;如果IO口为低电平,则需要判断是由于未按键还是扫描之前本来就是低电平引起的。
所以我们需要引入一个全局位变量KEY_EN,来标志按键的状态, KEY_EN=0表示按键未按下;KEY_EN=1表示按键按下。
另外,我们还需引入一个全局字节变量KEY_TP来暂存键值,这是因为只有当IO口电平变化满足高电平→低电平→高电平,才表示一个按键有效,而只有在IO口为低电平的时候才能够读取到键值。
具体的键盘扫描流程如图2所示,键盘初始化KEY_EN=0。
图1 传统键盘扫描
图2 改进后键盘扫描
接下来我们介绍一种代码效率极高的键盘扫描方法。
键盘接口电路同样采用独立式,假设有8个按键,所有按键公共端接地,键盘扫描口为P0.7~P0.0,而且没有按键按下时为高电平,键盘扫描程序如下:
unsigned char Trigger;
unsigned char Continue;
void delayms(unsigned char n)
{
……
}
void key_scan()
{
unsigned char ReadData;
if (P0!=0xff&&Trigger==0x00) delayms(20);
ReadData = P0 ^ 0xff;
Trigger = ReadDate & (ReadData ^ Continue);
Continue = ReadData;
}
程序中的Trigger就是键值。
我们举个例子来说明。
①没有按键按下时,ReadData=0x00,Trigger=0x00,Continue=0x00。
②当键5按下时,P0.5检测到低电平,ReadData=0x20,Trigger=0x20,Continue=0x20。
③当键5未释放时,P0.5依然检测到低电平,ReadData=0x20,Trigger=0x00,Continue=0x20。
④当键5释放时,P0.5检测到高电平,ReadData=0x00,Trigger=0x00,Continue=0x00。
可见,按键每按下一次,Trigger值只会变化一次,而Continue值用来判断按键是否释放,因此可以通过计时Continue值不变的时间来区分短按键和长按键。
另外,如果一个应用系统中既包括点触型按键,又包括常触型按键,则可以用Trigger表示点触型按键,用Continue表示常触型按键。
对于按键数目较多的应用场合,如25个按键,不管采用行列式键盘接口,阶梯式键盘接口,还是其它各类接口,只需要对以上的扫描方法稍加修改即可,这里不作分析,请自行分析。