欢迎大家mail至 dong@dongeasy.com讨论!
按键扫描是每个搞单片机的都会遇到的问题,也是一个开发人员必须具备的基本功。
通常的按键扫描程序是这样做的
很多教材上都是这样写,但这个程序却是误人子第的
问题来了,这个程序不太好用,有时按一下,或按久一点,程序会认为你按了很多次!!为什么???
因为没有判断按键释放,当我们按下键盘时,程序可能已经跑了N个来回了。好了,我们来个改进版的按键扫描程序
这是大多数人的按键扫描程序,在一般的场合也能用。这个程序比第一个要好点,但也好不到哪里去。为什么?判断按键释放的方法太笨了,如果我们一直按下这个键盘会怎么样?程序在此死等,可能你说我还有中断,但中断处理完了你还得回来傻等!而且其他按键也将被屏蔽。
那么,该怎么做。。。
先假设按键平时是高电平,按下后是低电平。也就是按键低电平有效;
那么一个完整的按键过程会发生什么?按键输入脚电平变化顺序是 高 -> 低 -> 高, 对应按键状态:未按->按下->释放;
好的按键扫描程序不是判断按键是否被按下,而是判断按键电平变化的变化顺序是否符合 高->低->高 状态 ,其他的按键电平变化顺序都是非法的 。这就是按键扫描的基本原理。
那么该怎么来判断呢?
进入按键扫描后,我们可能会扫描到高电平,那么就需要判断到底是未按键导致的高电平还是按下后键释放导致的高电平,这里用一个位变量(取名为键前状态,1=曾经按下,0=未按下)做为标志就可以了;
也可能会扫到低电平,那么需要判断这个低电平是由未按键到按下键得到的,还是扫描之前本来就是低电平,这里也用一个位变量(取名为按键有效,1=有效,0=无效)做为标志。好了,下面给一个简单的流程
主程序初始化操作,键前状态=0,按键有效=0
按键扫描流程
为了突出重点,这个流程没有加去抖处理,想要稳定的效果,必须加延时去抖处理。按这个流程处理按键,响应速度快,
也不会误判。你就是按一天也,不会傻等。按键有效之后,每次只进来看一下就走。最大的好处就是可以实现真正的模块化
按键处理完全由这个程序控制,不必在其他地方判断按键释放没有。
另外再简单谈一下长按,短按的判断。要判断长按,在按键有效之后(*2处)启动定时器,然后在(*3处)后判断时
间的长短,大于一定时间算长按。至于组合键盘的处理,在上面的流程上稍加改动就可以实现。