打印

按键可有**了,能体现一个人的编程水平

[复制链接]
27218|136
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
戒指320|  楼主 | 2009-7-26 14:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
传统的教科书,无一例外都是采用delay的方法检测按键,但是这种方法有很多缺陷,今天发一贴说说,各位大侠不要见笑,初级菜鸟可以借鉴。
传统的处理方法:在第一次检测到有键按下时,执行一段延时 10ms 的子程序以后再确认该按键电平是否能保持闭合状态的电平,如果保持闭合状态电平,则确认为真正有键按下,从而消除抖动的影响. 
缺点: 
1.  传统的处理方法执行 10ms 的延时子程序,会降低程序的实时性。 
2.  传统的处理方法一次按键动作的确认,只检测两次,在高抗干扰环境下的会有按键的误动作。
建议: 
1.  建议弹跳时间为 100ms 才可有效通过 EFT 杂讯认证。 
2.  建议主程序中连续检查 100ms 的稳定低电平才可认定按键按下成立。 
3.  相同道理连续检查 100ms 高电平才可认定按键弹起。 
4.  为了保证 MCU 的执行效率,按键的检测尽量不要使用 Delay 的方式,可以考虑采用轮询检测和计时器配合的方式进行。

方法如下:
在发现低电平后,我们每一个循环(时基)去读取一次电平,并与上次进行比较,若是相同则计数器加 1,直至达到足够的次数就进行处理,否则计数器清零,重新开始。

相关帖子

沙发
戒指320|  楼主 | 2009-7-26 14:11 | 只看该作者

同时这也包含了 分时处理  的思想

使用特权

评论回复
板凳
古道热肠| | 2009-7-26 14:26 | 只看该作者

哈哈,按键处理的确很有学问.

直接调用有阻塞的延时函数的确不可取.浪费CPU资源不说,更重要的是不好扩充功能.

使用特权

评论回复
地板
程序匠人| | 2009-7-26 14:35 | 只看该作者

需要100ms吗?

会不会有点显得迟钝?

使用特权

评论回复
5
戒指320|  楼主 | 2009-7-26 14:42 | 只看该作者

呵呵,我也从来没检测超过100ms  30-50ms我觉得可以,100ms的确有点迟钝。这个嘛可以调节。

使用特权

评论回复
6
myfaith| | 2009-7-26 15:32 | 只看该作者

低电平检测100ms

高电平也检测100ms,一次按键200ms,手脚不灵的人按键才会这么慢吧

使用特权

评论回复
7
oldli| | 2009-7-26 16:06 | 只看该作者

延时是必须的

可以设键标志,用一个或数个工作程序段的运行本身作延时。这样就不会有停止等待。
如果定时器空着,也可以用来数数。
100mS是太长了,15mS左右是合适的。

使用特权

评论回复
8
戒指320|  楼主 | 2009-7-26 16:23 | 只看该作者

O

请大家不要再对这个100ms发起讨论,前面说过这个可以调整。还有,有的情况下是不需要检测按键放开的。

七楼大哥 说用其他程序段代替延时程序也可取,关键这个代替延时的程序段每次执行所花费的时间固定吗?
 我的意思是用 时基 来计时  ,设定一个变量 cnt  假如程序的主时基是4ms的话 当检测到按键按下的时候 inc cnt  下一个回圈 再检测按键,如果还按下的话,cnt 再加一 ,当加到某个值的时候 可以认为 按键确实按下了这期间如果检测到又一次没按下,则clr cnt 重新开始。如果取cnt=10 则消抖时间是10*4=40ms

贴出小弟的一段程序,
时基是2ms
key_scan:
    mov    a,#01110000b    
    or    p0,a
    mov    a,#01111000b
    mov    p0ur,a
    mov    a,#10000000b
    mov    p0m,a
    mov    a,#00000111b
    or    p4,a
    mov    p4ur,a
    mov    a,#00000000b    ;com3输入,关led
    mov    p4m,a
    jmp    $+1
    jmp    $+1
    jmp    $+1
    mov    a,p4
    and    a,#00000111b
    mov    new_key,a
    bclr    fc
    rlcm    new_key
    rlcm    new_key
    rlcm    new_key
    mov    a,p0
    and    a,#01110000b
    mov    r,a
    bclr    fc
    rrcm    r
    rrcm    r
    rrcm    r
    rrcm    r
    mov    a,r
    or    new_key,a;00******=00seg6 seg5 seg4 seg3 seg2 seg1                 
    bts0    f_key_rel    
    jmp    key_scan10    ;检测放键
    jmp    key_scan20    ;检测按键
key_scan10:
    mov    a,new_key
    cmprs    a,#00111111b
    jmp    key_scan30
    incms    key_cnt
    mov    a,key_cnt
    cmprs    a,#15        ;30ms
    jmp    key_scan90
    bclr    f_key_rel
    jmp    key_scan30
key_scan20:
    mov    a,new_key
    cmprs    a,old_key
    jmp    key_scan21
    incms    key_cnt
    mov    a,key_cnt
    cmprs    a,#30        ;60ms
    jmp    key_scan90
    clr    key_cnt
    jmp    key_scan40
key_scan21:
    mov_    old_key,new_key
key_scan30:
    clr    key_cnt
    jmp    key_scan90
key_scan40:
    mov    a,new_key        
    cje    a,#00111111b,key_scan90    ;无键按下不作处理
    cje    a,#00111110b,key_scan41
    cje    a,#00111101b,key_scan42
    cje    a,#00111011b,key_scan43
    cje    a,#00110111b,key_scan44
    cje    a,#00101111b,key_scan45
    cje    a,#00011111b,key_scan46
    cje    a,#00001111b,key_scan47 
    jmp    key_scan90        
key_scan41:
    mov_    event_buf,#1        ;POWER键键值1
    jmp    key_scan80
key_scan42:
    mov_    event_buf,#2        ;osc键键值2
    jmp    key_scan80
key_scan43:
    mov_    event_buf,#3        ;HI/LOW键键值3
    jmp    key_scan80
key_scan44:
    mov_    event_buf,#4        ;timer键值4
    jmp    key_scan80
key_scan45:
    mov_    event_buf,#5        ;+auto键键值5
    jmp    key_scan80
key_scan46:
    mov_    event_buf,#6        ;-auto键键值6
    jmp    key_scan80
key_scan47:
    mov_    event_buf,#7        ;+-auto同时键值7
key_scan80:
    bset    f_key_rel
    call    wrt_FIFO        ;将键值写入event_FIFO
key_scan90:
        ret

使用特权

评论回复
9
gaohq| | 2009-7-26 17:40 | 只看该作者

能否上个C语言的注释全点的让我等初学看看。

时基 ?。。。。。
定时器中断X次就是一个时基?
检测到有键按下,A=0,定时中断一次 A++,
IF(A==20)比较键值,相同就确定有键按下?

使用特权

评论回复
10
ayb_ice| | 2009-7-26 18:05 | 只看该作者

有多任务思想这个问题就好解决

使用特权

评论回复
11
lwd110| | 2009-7-26 18:10 | 只看该作者

没看出和教科书有什么实质区别啊?

使用特权

评论回复
12
hyg1984| | 2009-7-26 20:17 | 只看该作者

板凳

观看

使用特权

评论回复
13
tyw| | 2009-7-26 21:09 | 只看该作者

要是这个软件延时用定时方法实现了呢?哈哈

在定时中断里做一个1mS的公共时标
当有键按下时对这个公共时标计数,比如计数30,则再检查键状态

使用特权

评论回复
14
yewuyi| | 2009-7-26 21:26 | 只看该作者

老掉牙的东西还有人讨论,说明老辈人写的书太差

呵呵。。。

使用特权

评论回复
15
程序匠人| | 2009-7-26 22:35 | 只看该作者

教科书误导了一茬又一茬的白菜

尽信书则不如无书

使用特权

评论回复
16
戒指320|  楼主 | 2009-7-26 22:56 | 只看该作者

继续顶

使用特权

评论回复
17
iC921| | 2009-7-26 23:47 | 只看该作者

100ms太久,只争1ms

使用特权

评论回复
18
iC921| | 2009-7-26 23:49 | 只看该作者

现在的按键形式可丰富

使用特权

评论回复
19
s46410864| | 2009-7-27 08:19 | 只看该作者

延时长点不要紧

延时100MS,不算多,我们按一下的时间也不少,
100MS,比复位的时间还短,应该可以,而且最大的程度去抖动.
保证了键盘的稳定性,不错,还有如LZ所说DELAY不环保,用定时轮询..
很好的按键产生了..哦HOHO

使用特权

评论回复
20
gaohq| | 2009-7-27 08:57 | 只看该作者

大侠

可以设键标志,用一个或数个工作程序段的运行本身作延时。这样就不会有停止等待
_______________________________________________________
这个是怎么搞的呢?

使用特权

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

本版积分规则

37

主题

290

帖子

2

粉丝