打印

按键的问题

[复制链接]
1806|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
472666GAQ|  楼主 | 2010-6-29 15:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
invinliang| | 2010-6-29 15:27 | 只看该作者
按键有很多类型啊,长按键啊,短按键啊……
所以……

使用特权

评论回复
板凳
Hezhiqiang| | 2010-6-29 15:38 | 只看该作者
去除按键抖动,去除外部干扰!
假如你的按键处理事件非常短,不做延时处理可能会判断有几次按键按下的可能!
按键也为机械接触开关,正常情况下,按一次按键,在按下瞬间,可能会有很多毛刺出现,就会有很多低平出现,所以要延时确认,即使没有这种情况,也要做延时处理,这样做是去干扰!正常情况下一个干扰脉冲也不可能会长达10-20MS.所以去干扰去抖动还是很有必要的。而这点时间对一个按键按下并不影响效果!

使用特权

评论回复
地板
dgchina| | 2010-6-29 15:39 | 只看该作者
延时10ms~20ms,防按键抖动功能

使用特权

评论回复
5
472666GAQ|  楼主 | 2010-6-29 16:05 | 只看该作者
我的意思是保留第一次判断和延时  把延时后的那次判断省略掉

使用特权

评论回复
6
black.lu| | 2010-6-29 16:29 | 只看该作者
回复LS,如果你将延时消斗后的判断去除,只读取第一次的键值。会衍生出两个问题:
1、在符合按键的情况下,按键键值会受到干扰,有可能按键一次就触发了复合按键,所以需要延时判断。
2、如果单按键的情况下,你是不是硬延时来消斗?这样做不合理,程序实时性没有保证。
按键消斗好处很多,普通情况下我们看不出效果,如果在高频干扰强的场合按键会乱触发,所以LZ还是不要有其它想法了。

使用特权

评论回复
7
472666GAQ|  楼主 | 2010-6-29 18:40 | 只看该作者
谢谢了

使用特权

评论回复
8
zq1987731| | 2010-6-29 20:11 | 只看该作者
如果要像LZ这么用...
“我的意思是保留第一次判断和延时  把延时后的那次判断省略掉”
那么这样自然是成功避免了第一次【按下】动作所产生的抖动,下面是一次按键完整过程:
━━高电平━━①VVV抖动VVV______②______低电平____________③VVV抖动VVV━④━高电平━━
①——这里是你的第一次判定,判定为“有按键”
②——这就是你所谓的“第一次判断和延时”后到达的地方,这时候顶多作为【按键按下】事件进行处理
③——这时候就产生问题了,按你的程序在②处应该已经把按键功能处理掉了,那么应该会将将此处的抖动误认为【第二次按键】
④——实际上到这里才算是【一次按键过程的结束】
也就是说~~~如果你在①处检测到按键,延时到②处开始执行【按键功能程序】,并且在③之前该【按键功能程序】执行完毕了,那么就产生【一键多判错误】
当然有些极端情况可以避免该错误
比如——
在①处检测到按键,延时到②处开始执行【按键功能程序】,执行到④该【按键功能程序】才完成
又比如——
在①处检测到按键,不延时直接执行【按键功能程序】,执行到④该【按键功能程序】才完成
以上两种情况都可以正常判定并执行按键功能且不会一键多判
但带来的问题:
1,①~③之间的时间是不可控的,难不成规定用户一键按下去100ms必须松手?
2,一次按键100ms算相当手快了吧,一个【按键功能程序】要执行那么久,99%存在架构上的严重问题

其实许多在校学生都很喜欢这么写...这里举个例子:
if(KeyScan == 0)    // 如果检测到低电平
{
    delayms(10);    // 等待10毫秒死机式
    if(KeyScan == 0) // 消抖结束,按键状态仍是低电平
    {
        while(KeyScan == 0); // 等待按键松开变回高电平
        Function();    // 执行按键功能程序
    }
}
上面这段很多人学生时代都写过,教科书上也是这么教的,看上去又简单又直观
1,delayms(10);
2,while(KeyScan == 0);
可上面2处重大拖慢系统的语句...真正的产品里可是不允许出现的...

所以...这年头大家玩按键..."0延时"的状态机结构才是主流
再简单举个例子:
定时器定个时基,状态机初始状态“等待按键”,每10ms检测一下按键状态,当检测到低电平,实际就是由①进入②的事件产生了,那么直接跳转状态至“有按键产生”,10ms之后再次检测时候仍是低电平,如果是...产生一个事件【按键被按下】,同时状态跳转至“等待按键放开”,然后只要检测到10ms后仍为低电平,说明按键未释放,那就使相关计数器增一,用来判断长短击,状态不变,若检测到高电平,产生一个事件【按键被释放】,并将状态跳转至初始状态“等待按键”,如此反复。
当然,上面的状态机还有很多细节没有处理,实际使用还有不少细节要完善,这样效率可远高于delayms(10ms)这样使系统“死机”10毫秒的方式...

使用特权

评论回复
9
kuguali| | 2010-11-9 13:38 | 只看该作者
我来学习一下。

使用特权

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

本版积分规则

102

主题

285

帖子

2

粉丝