马上注册,看完整文章,学更多FPGA知识。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
—边缘检测工程按键消抖详细解析
作者:小黑同学 本文为明德扬原创文章,转载请注明出处!
1.1 硬件电路
明德扬采用MP801开发板来进行边缘检测项目,在开发板中按键的实际位置如下图所示:
明德扬MP801开发板采用4个独立按键加一个复位按键,其中最左边为复位按键,并且采用上拉的连接方法,默认为1,当按键按下时,按键的电平被拉低。按键的电路原理图如下所示:
1.2 按键原理
MP801开发板上的按键为机械式开关结构,此机械式开关的是具有弹性的,因为其核心部件为弹性金属簧片,那么在开启或者闭合的瞬间会在接触点出现来回弹跳的现象,即我们说的按键抖动。当然这种情况并不是只在MP801开发板上出现,现阶段下绝大多数的按键都是机械式开关结构,这是无法避免的问题。
虽然只是进行了一次按键,其实在按键信号稳定的前后出现了多个脉冲,实际产生的波形如下图所示:
在按键闭合和断开的瞬间,我们其实只需要一组稳定的上升沿和下降沿,但是实际情况却产生了若干个沿。因此在实际的电路中,如果将这样的信号直接传送给微处理器扫描采集的话,那就存在把抖动信号当做按键信号的可能,这样虽然只按了一次按键,但是微处理器却认为按了多次按键。为了可以达到按一次按键就可以得到一次识别的效果,就需要对按键进行消抖处理,消除按下按键时不稳定、随机的抖动电压信号。机械式按键的抖动次数、抖动时间、抖动波形都是随机的,不同类型的按键的最长抖动时间也不同,抖动时间的长短和按键的机械特性有关,一般为5到10ms,但有些按键的抖动时间可达到 20 ms甚至更长。因此,具体设计中要具体分析,根据实际情况来调整设计。
1.3 按键捕捉
有些同学看到按键消抖处理,就理所应当以为是将按键按下这一活动的抖动部分进行消除,但其实按键的消抖只是一种比较正式的说法,其本质上是在抖动的波形中,捕捉到比较稳定的电压。 我们通过实际情况来学习下。一般按键都是低电平有效,通常情况下按键信号为高电平,当主动按下按键时会变成低电平,这是按键的基本电平情况。前面我们有说到,在按下的瞬间,稳定状态的信号前后都会产生抖动,这时即使按键信号等于0也无法表示按键被按下。 为了解决这一问题,我们对此进行了思考,不论信号为抖动信号还是正常信号,都对此进行采集,并对其进行监控,如果信号变0,就可以暂时的判断为进行了按下按键操作。接着我们来判断持续时间,当此操作只持续了一瞬间,信号就变回了1,那么可以判断为按键抖动;反之如果信号为0持续了一段时间并且趋于稳定,那么就可以判断此操作为按下按键。明德扬管这种行为叫做按键捕捉,在按键信号中捕捉到持续一段时间的低电平信号,判断为按下按键的有效操作。关于持续时间的判断,明德扬使用的MP801开发板抖动时间比较短,低电平信号持续10ms以上就可以判断为按下按键的行为成立。
如下图所示,按键持续为高电平,当按下按键的时候会变为低电平,但是在此前后都会产生一段高高低低的抖动信号。按键捕捉的方法就是持续的检测信号的进度,比如到第一个低电平产生时,开始计时,假设第一个出现的低电平持续时间为6ms,不满足按键按下标准;第二个低电平信号出现持续时间为8ms,不满足按键按下标准;到第四个低电平信号,持续了10ms以上,满足按下按键标准,即可判断这里有一次的按下按键操作;接着第五个低电平信号,持续时间为6ms,不满足按下按键标准。这种方法,就可以帮助我们很好的确判断有效按键信号。
我们将捕捉到的持续10ms以上低电平状态的信号提取出来,就是表示按下按键操作的信号。在这里,明德扬会选择产生一个有效指示信号key_vld来表示按键的状态。此信号初始状态为低电平,当捕捉到按键按下操作时,信号key_vld会变为高电平,持续一个时钟周期,然后重新变为低电平。这时我们只要通过判断key_vld信号的状态,如有没有变为高电平、出现了几个高电平,就可以判断按键是否按下以及按下几次按键。这里需要注意,key_vld信号不是代表按键的按下的低电平信号,而是已经完成了按键捕捉的环节,对捕捉到的成功按下按键结果的一个表现。持续一个时钟周期也并不是说按键信号持续了一个时钟周期,而是向大家更加清晰的表示,这里进行了按下按键操作。
这里可以理解为,当捕捉到一个持续10ms以上的低电平信号,信号key_vld会举手示意一下,再次捕捉到下一个时,信号key_vld会再次举手示意一下。信号key_vld就如它的类型一样,为有效表示信号,只是表示按下按键的有效操作,不做其他。
如下图所示,我们增加了一个key_vld信号,此信号在这段时间内拉高了一个时钟周期,这就可以判断按键按下了一次。
1.4 按键消抖的实现 前面有提到按键消抖并不是消除抖动,而是在有抖动的基础上进行一定的操作从而更加准确的判断按键操作的有效性,实现按键消抖有硬件方法和软件方法。
硬件消抖的原理很简单,就是在按键上并联一个电容,如下图,利用电容的充放电特性来对抖动过程中产生的电压进行平滑处理,从而实现消抖。原理前面也有详细的讲述
但实际应用中,由于这种方式的效果不佳,会有一定的不稳定性,增加了电容后由提升了电路的复杂程度,并且硬件的增加也令成本提高,综合考虑后,明德扬更多的是采用软件即程序来实现消抖的。 前面我们讲了捕捉到了足够时间的信号,判断为有效按键,明德扬的软件消抖方法即使用计数器实现消抖。前面有讲到,按下按键的操作会产生低电平,但是由于按键的抖动,导致并不是产生固定的一段低电平,而是在前后会有短时间的高低电平波动。那么我们就增加一个计数器,用来数低电平持续时间,当持续时间达到10ms的时候,判断完成一次有效按键操作,当低电平持续时间不足10ms的时候,即判断为按键抖动,不做有效判断。
不同按键的抖动时间不同,这样通过软件实现按键消抖的方式,对于不同的按键可以设计不同的计数器计数时间,更具有稳定性,也节约了一定成本,非常建议大家使用。
1.5 按键采集实现
理解了按键工作的原理,我们来在FPGA中实现按键采集。
我们先将设计目标使用波形图表示出来,如下图所示,按键信号定义为key_in,持续为高电平状态即1,变0表示按下按键,并且按下按键的时间是不确定的;由于按键信号key_in属于异步信号,必须寄存两拍,第一拍key_in_ff0将信号同步化,第二拍key_in_ff1减少亚稳态带来的影响。当信号key_in_ff1变0时,计数器开始计数,计数器数够10ms表示按下按键;增加一个信号flag初始状态为0,当计数器数够10ms时信号变1,当key_in_ff1结束变1时,flag信号变0,表示按键操作结束;增加一个key_vld信号,当计数器数够10ms时拉高1个时钟,表示成功按下一次按键。
根据波形图一起来进行代码的实现,将信号key_in异步信号同步化代码表示如下图所示:
接着来将计时器用代码表示出来首先计数器的加一条件,根据波形图可知,当key_in_ff1并且flag==0的时候,计数器加1条件成立。关于计数器数多少下,有目的可知道,当按键低电平持续时间足够10ms即按键动作有效,因此计数器数10ms,我们使用的时钟频率为50Mhz,那么一个时钟周期就是20ns,要数够10ms,就需要500000个时钟周期,又因为计数器是从0开始计数的,所以计数器的结束条件就是500000-1。
因此计数器的代码表示如下所示:
接着标志信号flag,信号处于低电平状态,当计数器数够500000下,标志着按键操作成立,flag信号拉高,当key_in_ff1变1,标志着按键动作结束,因此flag的代码表示如下:
当计数器数完10ms时,我们需要key_vld信号产生一个时钟周期的高电平输出,表示一次按键操作,因此当end_cnt时,信号变1,代码表示如下:
以上就是使用按键采集的整个过程,其中包含了按键信号消抖和信号捕捉,我们再来做一个总结,当遇到有抖动产生的按键,就设置一个信号持续时间门槛,当信号持续时间达到这个门槛,可以判断为有效按键信号,当无法达到这个门槛,则按下按键操作不成立。达到门槛的信号,即代表了一次按键操作成立,整个操作中,达到了几次门槛,就代表按下几次按键。代码是以适配本工程硬件来写的,但是道理都是相通的,后续读者朋友们遇到按键消抖的问题可以使用这种方法解决。
|