打印

键盘去抖的处理方法

[复制链接]
2342|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
醉心369|  楼主 | 2013-4-25 15:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 醉心369 于 2013-4-25 16:12 编辑

        用一个变量来记录按键状态,规定该变量为0 表示按键松开,达到规定值表示按键按下。先将这个变量初始值设为规定值的一半,在程序主循环或者定时中断中循环间隔查看按键状态,松开减一,按下则加一,直到变量到达0 或者规定值,这种方法一样可以起到很好的去抖效果,而且不需延时等待时间。
       关于这个方法,我不是很理解,烦请大侠们给看看。

相关帖子

沙发
ayb_ice| | 2013-4-25 16:08 | 只看该作者
定时调用即可,按下加一,没有按下清零,当达到一定值表示按下(比如3),再达到一定值表示长按下(比如100)
后面还可以扩展更多,比如持续按下,释放等

使用特权

评论回复
板凳
zd420325| | 2013-4-25 17:34 | 只看该作者
这是有的代码,差不多是按你说的那样写的,不过有点不同,自己想出来的,反正是能正常识别,抗4KV的EFT干扰没有问题,测试过的。

void KeyScan(void)
{
        wdreset
        if ( KeyScanF )//每10ms进入一次按键扫描;
        {
                KeyScanF = 0;
                .DELAY 150//延时一段时间,待电容放电.
                if ( KEY == 0 )//有按键按下
                {
                        if ( KeyScanCounst < 200 )//计时仿止溢出;
                        {
                                KeyScanCounst++;
                        }
                        switch (  KeyScanCounst )
                        {
                                //case 1,2 延时扫描
                                case  8:
                                {
                                        delay 3
                                        if ( KEY == 0)//再次判断是否有键按下
                                        {
                                                if( onoffF == 1 )
                                                {
                                                        onoffF = 0;
                                                }else
                                                {
                                                        onoffF = 1;
                                                }
                                        }else
                                        {
                                                KeyScanCounst = 0;
                                        }
                               
                                }break;
                                default :
                                {
                                        if ( KEY == 1 )//如果没有按键按下,则认定为干扰或者抖动,计数清0
                                        {
                                                KeyScanCounst = 0;
                                        }
                                }break;
                        }
                }else //if ( KEY == 1 )
                {
                        KeyScanCounst = 0;
                }
        }
}

使用特权

评论回复
地板
zd420325| | 2013-4-25 17:37 | 只看该作者
上面用到延时,是因为按键并联的有电容,等待电容放电后再判断。如果不用电容,则可以不要那个延时,不过这与你的要求不用delay();是不冲突的。

使用特权

评论回复
5
longdeng84| | 2013-4-26 10:57 | 只看该作者
用状态机思路写按键。。

使用特权

评论回复
6
醉心369|  楼主 | 2013-4-27 13:35 | 只看该作者
zd420325 发表于 2013-4-25 17:37
上面用到延时,是因为按键并联的有电容,等待电容放电后再判断。如果不用电容,则可以不要那个延时,不过这 ...

当有按键按下的时候,KeyScanCounst为1的时候, switch语句没有判断case 1的情况,如果没有case 1,此时不就进入
                                default :
                                {
                                        if ( KEY == 1 )//如果没有按键按下,则认定为干扰或者抖动,计数清0
                                        {
                                                KeyScanCounst = 0;
                                        }
                                }break;
下面这个函数了吗,此时KeyScanCounst = 0;不就一直是死循环了吗,根本进入不到case 8的流程。

使用特权

评论回复
7
zd420325| | 2013-4-28 10:43 | 只看该作者
if ( KEY == 1 )//如果没有按键按下,则认定为干扰或者抖动,计数清  
{
    KeyScanCounst = 0;
}

按下时KEY == 0 ;//Default 里面是再判断,抗干扰的。

使用特权

评论回复
8
zd420325| | 2013-4-28 10:44 | 只看该作者
上面的代码是从我做成功的项目里面拷过来的

使用特权

评论回复
9
醉心369|  楼主 | 2013-4-29 16:35 | 只看该作者
当有按键按下的时候,首先KeyScanCounst就等于为1,我理解的对吗?
如果上面这段话,我理解正确的话,就会进入switch语句,因为没有switch(1)的情况,所以就如入了default语句。
      default :
                                {
                                        if ( KEY == 1 )//如果没有按键按下,则认定为干扰或者抖动,计数清0
                                        {
                                                KeyScanCounst = 0;
                                        }
                                }break;
此时KeyScanCounst = 0;
这样,不就一直是死循环了吗,从1到0,再从0到1,根本进入不到case 8的流程。

使用特权

评论回复
10
zd420325| | 2013-5-2 14:51 | 只看该作者
   if ( KeyScanCounst < 200 )//计时仿止溢出;
                        {
                                KeyScanCounst++;////////////哎,楼主啊。++,看到了吗
                        }

使用特权

评论回复
11
MCU_Jason| | 2013-5-2 17:29 | 只看该作者
default :
                                {
                                        if ( KEY == 1 )//此时如果按键一直被按下,KEY == 0,程序不会执行KeyScanCounst = 0,程序跳出switch,继续执行KeyScanCounst++;如果此时KEY == 1,说明按键抬起,此时认为是干扰,KeyScanCounst被清零,重新扫描按键。
                                        {
                                                KeyScanCounst = 0;
                                        }
                                }break;

使用特权

评论回复
12
醉心369|  楼主 | 2013-5-2 21:04 | 只看该作者
zd420325 发表于 2013-5-2 14:51
if ( KeyScanCounst < 200 )//计时仿止溢出;
                        {
                             ...

看到了,要是没看到的话,该值KeyScanCounst 就一直为 0了。看到11楼的似乎明白了,该程序是适合短按吗?一般来说一次按键大约有30ms,,假如还没有30ms已经过去了,你的KeyScanCounst还没有到8,那此次按键就跳过了,是否存在这样的情况

使用特权

评论回复
13
xudong008| | 2013-5-2 21:09 | 只看该作者
其实就是判断按键的状态,就是我们说的状态机呀!!!

使用特权

评论回复
14
醉心369|  楼主 | 2013-5-2 21:27 | 只看该作者
xudong008 发表于 2013-5-2 21:09
其实就是判断按键的状态,就是我们说的状态机呀!!!

用定时器定时扫描的话,应该是状态机。如果不用定时器,而是用循环扫描的话,还是状态机吗

使用特权

评论回复
15
liub_2014| | 2013-5-4 00:33 | 只看该作者
我觉得看应用而定了, 如果只是简单的判断是否有按键,不用这么复杂吧

使用特权

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

本版积分规则

60

主题

283

帖子

2

粉丝