按键去抖分析

来源:互联网 发布:华中大数据交易所 编辑:程序博客网 时间:2024/05/16 08:33

来自QQ群 Linux && 技术分享 311078264 

如果有兴趣的话可以加入进来一起学习,共同进步。
个体的精力总是有限的,分享经验,互助互利才是快速上升的捷径。


一、按键分析

  按键按下去分为以下几种:
1、按下立刻弹起,识别为一次按下动作
这种情况下,闭合时间取决于人手的按键速度,但是通常都在100ms以上
2、按下不抬起(保持一段时间),识别为单次点击或者连续点击
3、按下不抬起是一个状态(闭合保持),然后抬起是另一个状态(断开保持)

检测按键可以用两种方法:
1、电压检测,需要不断扫描IO电平,比较消耗CPU资源
2、中断检测,不必持续检测,节省CPU的资源

按键抖动情况:
1、电压检测
按键刚按下和抬起的时候,电平是不稳定的,需要考虑去抖。
按键动作会有一段稳定的状态,一般采用延迟采样或者持续采样就能解决这个问题。
2、中断检测
中断状态下,有可能按下一次产生超过一次中断,比较多见的是触发两次中断。
解决这个问题,需要考虑按键动作的时间,在一段时间内发生的多次中断都要识别为一次。
并且,中断检测方式不能用于保持按下按键,持续产生按键动作的情况。   

二、按键抖动原因


    通常按键所用的开关都是机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上就稳定的接通,在断开时也不会一下子彻底断开,而是在闭合和断开的瞬间伴随了一连串的抖动.

file://C:\Users\elikang\AppData\Local\Temp\ct_tmp/1.png

按键稳定闭合时间长短是由操作人员决定的,通常都会在100ms以上,刻意快速按的话能达到40-50ms左右,很难再低了。

抖动时间是由按键的机械特性决定的,一般都会在10ms以内,为了确保程序对按键的一次闭合或者一次断开只响应一次,必须进行按键的消抖处理。当检测到按键状态变化时,不是立即去响应动作,而是先等待闭合或断开稳定后再进行处理。


三、按键去抖分析

按键消抖可分为硬件消抖和软件消抖。

硬件消抖:
利用电容的充放电特性来对抖动过程中产生的电压毛刺进行平滑处理,从而实现消抖。
但实际应用中,这种方式的效果往往不是很好,而且还增加了成本和电路复杂度,所以实际中使用的并不多。
file://C:\Users\elikang\AppData\Local\Temp\ct_tmp/1.png


软件实现消抖:
通过延时程序过滤。
最简单的消抖原理,就是当检测到按键状态变化后,先等待一个10ms左右的延时时间,让抖动消失后再进行一次按键状态检测,如果与刚才检测到的状态相同,就可以确认按键已经稳定的动作了。

如果需要更精细的检测,可以考虑结合持续对IO状态进行采样来去抖。

======================

软件去抖的几个思路:

1、延迟
先定义一个变量记录按键的状态:char key;
然后轮询检测按键状态,当按键状态改变的时候,判断为有按键动作,接下来进入延迟函数;
等到延迟时间过了之后,再读取按键状态,如果按键状态仍为按下状态,则说明确实是有按键动作,不是抖动。

2、中断加延迟方式
单片机总是轮询状态会浪费很多资源,尤其是单片机运行的时间,可以通过中断方式来解决。
中断模式下,单片机不需要轮询按键状态,当有中断产生的时候才会进入延时函数,进行按键去抖程序。

这种情况下,延时函数在哪里进行处理就有两种选择:
一种是放在中断函数中进行,这个时候中断函数占用的时间就比较长,影响响应速度;
另一种是放在中断函数之外进行,这个时候就缩短了中断处理时间,但是这个时候就需要一个标志位来表明是否有中断产生,而且单片机也需要不断查询,只是节约了查询时候读取IO状态的步骤。

3、持续采样
持续采样会大大提高采样的准确度,但是同时也会增加CPU的开销。
在使用中,需要根据需要选择不同的采样频率,一般每10ms采集一次就足够了。

==
关于延迟方法:
简单的延时,可以采用空循环来实现,这个方法比较消耗CPU的资源,CPU任务较重的时候不建议使用。延时函数可以考虑使用定时器替换,但这又消耗了定时器资源,不过只要够用的话还是尽量用,毕竟可以减轻CPU的负担。

关于一次按键过程中产生多次中断的处理:
一次按键过程,可能产生多次中断,可以设置一个标志位来显示是否处于按键识别处理阶段,如果处于按键识别处理阶段即便产生中断也不进行任何响应,这样就可以忽略多余的中断了。

四、我的按键去抖方案


1、使用中断检测按键触发


file://C:\Users\elikang\AppData\Local\Temp\ct_tmp/1.png
只有在int_flag为0的时候才会设置int_flag的值为1,此时只有在后续的处理完成后,才会将ing_flag重新设为0,才会响应下一次按键中断。这就消除了一次按键动作会产生多次中断的情况。

2、产生中断后,后续的按键处理程序,可以保证正确识别按键按下还是按键抖动
file://C:\Users\elikang\AppData\Local\Temp\ct_tmp/2.png

这里为了演示方便,直接使用了延时函数,实际使用中为了节省CPU开销,应该使用定时中断。





原创粉丝点击