上一篇文章 《Tiny4412 Linux驱动之按键(使用中断)》使用中断的方式写了按键检测驱动程序,但是有一个问题:有时候按下一次按键有可能输出两条信息的情况:
如上图所示,按下了一次,缺打印了两次,这是由按键抖动引起的。
按键消抖的原理
我们平常所用的按键为机械弹性开关,由于触点的弹性作用,按键在闭合时不会马上稳定的接通,而是有一段时间的抖动,在断开时也不会立即断开。抖动时间由按键的机械特性所决定,一般为5ms~10ms。所以我们在做按键检测时都要加一个消抖的过程。
按键消抖主要有两种方案:
一是延时重采样;
二是持续采样。
从理论上来说,延时(如10ms)重采样的准确率肯定低于持续采样。
按键消抖的方法
(1)延时重采样
延时重采样的意思是,当第一次检测到键值由'1'变为'0'时,再延时一段时间(如10ms),再次采样,确认是否仍是'0';若是'0'则认为此时键值为'0',否则,重新执行检测过程。
该方案的缺陷:a.如果延时太短,有可能两次采样时都处于抖动时间,因此可能引起误判;
(2)持续采样
持续采样的原理是,当检测到按键处于某电平(如'0')时,在之后的N个时钟周期内连续检测此按键的电平,如果一直不变,则读出此按键的电平值(如'0')。
持续采样的优点:a.样本足够多,减少误判的可能性。
b.对于按键按下('1'->'0'),按键释放('0'->'1')都可以检测。
持续采样的缺点:持续检测的时间太长(大于按键按下和释放的时间差),则可能无法检测按键的变换。
在这里我们使用的延时采样的方式,即:当某个键被按下后会触发中断,上一个试验中我们进了按键中断之后就唤醒读取函数,这样由于按键抖动可能会短时间内进好几次按键中断;现在我们加入内个定时器,当按键按下出发了按键中断之后,在按键中断里修改定时器触发时间(比如定时10ms)。
原理说完了,下面开始做测试:
还是一共三个文件,1驱动相关:. keyIrq_drv_timer.c Makefile
2.测试程序 : key_test_irq.c
实验步骤:
驱动和应用程序都编译出来之后,首先加载驱动:
insmod keyIrq_drv_timer.ko
如上图所示,加载完驱动之后,按键节点已经自动创建出来了,
下面开始测试;
输入 ./key_test_irq