长按短按一般是用来扩展按键功能,让人机界面更好用。其实现在做的最好的人机界面还是触摸屏上,iOS中对一个图标长按就激活了应用删除。除了长按,触摸屏还有短按、滑动,更牛逼的是手势操作,我现在累死累活做了个按键的长按短按处理,才发现触摸屏的使用有多牛逼,在用触摸屏的时候根本不用学,自然而然就会用触摸屏,这尼玛才是科技和人的结合啊!!!
当然,这一篇还是描述怎么做按键长按短按的,擦!
长短按的定义
- 长按是指按下按键超过一定时间,这里以2s为时间阈值。
- 短按是指从按下按键到弹起按键,不到0.5s。
实现
根据上面对长按短按的定义,可以这样设计:
按键按下的瞬间触发中断,然后每隔100ms轮询,如果超过2000ms,按键都是按下的,则发出长按消息,如果弹起,并且按下时间没超过500ms,则为短按。
OSAL的按键已经有轮询,计时,所以只需要小小修改一下就能实现。
首先,定义长按短按的标志位:
const uint8 HAL_KEY_SHORT=0x40; const uint8 HAL_KEY_LONG=0x80;
然后,在轮询函数HalKeyPoll()中加入计时
if (!Hal_KeyIntEnable) { if (keys == halKeySavedKeys) //如果中断关闭(轮询中),并且按键是保持按下的 { keypresslasttime++; //因为polling每100ms执行一次,所以当keypresslasttime=20时,发出长按的消息, if(keypresslasttime==20) //如果达到2000ms { sendkeys = keys | HAL_KEY_LONG; //加上长按标志 (pHalKeyProcessFunction) ( sendkeys, HAL_KEY_STATE_NORMAL); //发送按键消息 } else //如果没达到2000ms,则直接返回 { /* Exit - since no keys have changed */ return; } } else { //当按键弹起时,看一下按下的时间多长,因为polling的时间是100ms,所以当keypresslasttime<5时,发出短按的消息, if(keypresslasttime <5) { sendkeys = halKeySavedKeys | HAL_KEY_SHORT; (pHalKeyProcessFunction) ( sendkeys, HAL_KEY_STATE_NORMAL); } notify = 1; } } else { /* Key interrupt handled here */ //如果是按键终端,则开始计时 keypresslasttime = 1; if (keys) { notify = 1; } } /* Store the current keys for comparation next time */ halKeySavedKeys = keys; /* Invoke Callback if new keys were depressed */ if (notify && (pHalKeyProcessFunction)) { //(pHalKeyProcessFunction) (sendkeys, HAL_KEY_STATE_NORMAL); (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL); } }
顺便说一下,在实现key对应IO口配置的时候,要注意一下中断的触发方式,是上升沿触发还是下降沿触发。如果弹起时低电平,按下是高电平,就应该采用上升沿触发,这样才能正确计时。