打印

键盘扫描的消抖

[复制链接]
3993|34
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
heweibig|  楼主 | 2012-5-13 18:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
键盘扫描的消抖一般要延时多少时间
沙发
wuhany| | 2012-5-13 18:31 | 只看该作者
通常为数毫秒级别。

使用特权

评论回复
板凳
heweibig|  楼主 | 2012-5-13 18:33 | 只看该作者
是无时无刻的循环扫描好呢,还是每隔个时间扫描好?

使用特权

评论回复
地板
lizye| | 2012-5-13 18:33 | 只看该作者
简单系统可以串入主循环,则便是“无时无刻”扫描之。否则建议采用定时中断扫描,当然也可以采用按钮触发中断扫描。

使用特权

评论回复
5
heweibig|  楼主 | 2012-5-13 18:34 | 只看该作者
如果是隔着时间扫描,那么是不是可以不消抖?

使用特权

评论回复
6
jiahy| | 2012-5-13 18:35 | 只看该作者
无论是那种扫描都必须考虑消抖。

使用特权

评论回复
7
heweibig|  楼主 | 2012-5-13 18:36 | 只看该作者
恩,书上说抖动时间大约6ms,消抖10ms应该可以了。怎么才算复杂系统呢?
如果我每隔10ms扫描一次键盘,也可以用这个间隔做消抖,感觉上好像“没消抖”

bit   fg_shake;               =0
bit   fg_scan;                 =0

//中断中,每10ms就fg_scan=1;
void    main(void)
{
         -----;
         if(fg_scan==1)
         {
                    fg_scan = 0;
                    keyscan();
         }
}

void   keyscan(void)
{
         if(key_on ==1) //有键按下
         {
                   if(fg_shake==1)  //说明过了10ms
                   {
                               //按键处理
                   }
                   else   fg_shake=1;
         }
         else   fg_shake =0;
}

使用特权

评论回复
8
jiaxw| | 2012-5-13 18:36 | 只看该作者
你的程序虽然消抖了,但是没有防止单次击键下重复响应。一般情况下这是不允许的,即使是做连击功能,也该有个计时,以防响应过快。

使用特权

评论回复
9
heweibig|  楼主 | 2012-5-13 18:38 | 只看该作者
重复响应是说,按键抬起时没有清除按键标志就又按下键是吗?
好像问题不大吧,因为处理的时候,这样快速的按键可以认为一次按键。我一般单击按键是按照下降沿来处理的,如果是连击,10ms应该够反应了吧,也可以在处理时加个时间计数。。。

使用特权

评论回复
10
shimx| | 2012-5-13 18:38 | 只看该作者
扫描时间过快时会导致你一次按键多次响应的 ,不过可以通过加入一个标志位,在你长按的时候,如果标志位为1则说明之前已经执行过一次,下次就不要执行了,直接返回主程序,这样可以做到一次按键一次响应,同时运用好的话,可以用来做长键处理,只需加入一个长按时间计数则可

使用特权

评论回复
11
spark周| | 2012-5-13 18:39 | 只看该作者
教材上一般建议10ms左右,实践验证10ms也够了,当然还可以长点,只要符合你的按键反应要求就行了,实验去确定这个时间值。以前的一个产品中,用扫描的方式,延时大约9ms,效果还行。但如前面的朋友所言,楼主贴出的代码思路会造成多次进入按键处理部分,而且还不知道你的key_on是什么,是IO口状态还是其他内存变量。如果你采用边沿触发中断方式,还得看你用什么样单片机,有的单片机外部中断标志在进入中断服务程序后会自动清除,有的则需要软件人为清除,不论哪种方式,尽量不要中断中去抖。不管怎样,总有办法消除多次响应的问题,另外,建议进行按键释放判断,可以释放后再处理按键,也可以滤波认为有效按键则处理、待释放后再接受下次按键,这样能有效避免多次响应。

使用特权

评论回复
12
spark周| | 2012-5-13 18:39 | 只看该作者
恩,书上说抖动时间大约6ms,消抖10ms应该可以了。怎么才算复杂系统呢?
如果我每隔10ms扫描一次键盘,也可以用这个间隔做消抖,感觉上好像“没消抖”

bit   fg_shake;               =0
bit   fg_scan;            ...
heweibig 发表于 2012-5-13 18:36

这段代码还是有消抖效果的,如果不考虑省略号处程序的延时,这个消抖时间根据按键按下的时刻是不定的,在10ms~20ms之间,另外,用这个思路的话,主程序中省略号处不能占用太长时间,否则影响按键扫描的间隔。所以这个方法有一定局限性,感觉适用于任务调度的主循环模式。

使用特权

评论回复
13
liliang9554| | 2012-5-13 18:40 | 只看该作者
这个程序只是检测到按键后延时10ms执行按键处理,怎么能说是防抖?如果按键处因为干扰有一个按键触发,程序照样会执行按键处理。

如果手动按键最快的速度是100ms,程序应该在100ms里采样多次,每次的IO状态一样才能认为是有效按键事件

使用特权

评论回复
14
午夜粪车| | 2012-5-13 18:41 | 只看该作者
抖动是机械按键不可避免的,闭合和断开时都有抖动(即使干簧管也有抖动),延时就是为了确认有按键发生,通常情况下,抖动的过程5~10ms,最简单也最有效的方法就是上面讨论的延时。而14楼朋友说的干扰产生的误触发是不好处理的,最好通过硬件措施进行避免,比如并一个电容(这时候其实如果采用边沿触发,都可以不用软件滤波了),因为这个干扰触发得到的信号单片机一般没法区分是干扰还是按键抖动,除非这个干扰信号有规律而且特性上能与机械按键抖动区分开,我个人觉得如果这个干扰信号能足以以假乱真,逃过单片机的延时去抖,那么我想这个电路系统应该进行重新设计了^_^。而在长达100ms时间里多次采样的方法,是不太可取的,首先真要像14楼描述的那样,那么如果你在某个采样点刚好是抖动波形的零点,但确实有按键发生,该怎么取舍?而且,反复采样,CPU就不能在去抖的这么长的时间里去处理其他任务,系统的响应特性就会打折扣了。
回过头来,对于楼主的问题,不论是教材上的意见,还是本人的实践,至少对于一般使用的机械按键,10ms的去抖是可以的。

使用特权

评论回复
15
zhaoxqi| | 2012-5-13 18:42 | 只看该作者
10ms就可以了,我们导师就是这么说的。。。

使用特权

评论回复
16
jiajs| | 2012-5-13 18:42 | 只看该作者
机械抖动你可以根据实践的值推算5-10ms,延时防抖只是避免5-10ms内多触发按键事件,而没有防止误按、干扰等操作的功能,你只要检测到下降沿(或上升沿)就会触发按键事件,所以这样的程序并不可靠。一般正常手动按键不会低于100ms,采样间隔可以考虑大于机械抖动时间(这也是一般的做法,即10-20ms采样一次),其实做产品时对按键的检测用软件滤波比防抖更贴切一点。

而且,反复采样,CPU就不能在去抖的这么长的时间里去处理其他任务,系统的响应特性就会打折扣了。

没有人说让你死循环采样呀,要照你这么说你检测长按2s,难道MCU在2s内都不不能执行其他任务了,程序里都有定时器中断,你可以置个标志就可以做了,除非你的系统简单到只需要检测按键或其他任务在检测按键过程不需要执行

使用特权

评论回复
17
huangchui| | 2012-5-13 18:44 | 只看该作者
我的做法是例如定时1ms扫描一次键盘,若连续10次扫描到按键按下,则查询按键已经按下标志:
此标志为0则证明这是新的按下行为,置标志,处理按键程序;
此标志为1则证明按键已经按下,处理程序已经执行,不再重复执行。
扫描时发现按键释放,则清标志。

使用特权

评论回复
18
zhenykun| | 2012-5-13 18:44 | 只看该作者
如果有兴趣,研究一下用中断扫描,网上基于状态机的例程,只有三行代码

使用特权

评论回复
19
heweibig|  楼主 | 2012-5-13 18:45 | 只看该作者
扫描时间过快时会导致你一次按键多次响应的 ,不过可以通过加入一个标志位,在你长按的时候,如果标志位为1则说明之前已经执行过一次,下次就不要执行了,直接返回主程序,这样可以做到一次按键一次响应,同时运用好 ...
shimx 发表于 2012-5-13 18:38
你说到我心里了,我就是这样想的。。。

使用特权

评论回复
20
wyjie| | 2012-5-13 18:46 | 只看该作者
这样做有一个小小的特点,就是你长按之前他都处理了一下,有时候你不希望他发生,就必须采用抬起的那一个上升沿进行响应了 HOHO

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

869

主题

13089

帖子

7

粉丝