戒指320 发表于 2009-7-26 14:09

打破教科书上的按键检测方法

传统的教科书,无一例外都是采用delay的方法检测按键,但是这种方法有很多缺陷,今天发一贴说说,各位大侠不要见笑,初级菜鸟可以借鉴。<br />传统的处理方法:在第一次检测到有键按下时,执行一段延时&nbsp;10ms&nbsp;的子程序以后再确认该按键电平是否能保持闭合状态的电平,如果保持闭合状态电平,则确认为真正有键按下,从而消除抖动的影响.&nbsp;<br />缺点:&nbsp;<br />1.&nbsp;&nbsp;传统的处理方法执行&nbsp;10ms&nbsp;的延时子程序,会降低程序的实时性。&nbsp;<br />2.&nbsp;&nbsp;传统的处理方法一次按键动作的确认,只检测两次,在高抗干扰环境下的会有按键的误动作。<br />建议:&nbsp;<br />1.&nbsp;&nbsp;建议弹跳时间为&nbsp;100ms&nbsp;才可有效通过&nbsp;EFT&nbsp;杂讯认证。&nbsp;<br />2.&nbsp;&nbsp;建议主程序中连续检查&nbsp;100ms&nbsp;的稳定低电平才可认定按键按下成立。&nbsp;<br />3.&nbsp;&nbsp;相同道理连续检查&nbsp;100ms&nbsp;高电平才可认定按键弹起。&nbsp;<br />4.&nbsp;&nbsp;为了保证&nbsp;MCU&nbsp;的执行效率,按键的检测尽量不要使用&nbsp;Delay&nbsp;的方式,可以考虑采用轮询检测和计时器配合的方式进行。<br /><br />方法如下:<br />在发现低电平后,我们每一个循环(时基)去读取一次电平,并与上次进行比较,若是相同则计数器加&nbsp;1,直至达到足够的次数就进行处理,否则计数器清零,重新开始。<br />https://bbs.21ic.com/upfiles/img/20097/200972614416718.jpg

戒指320 发表于 2009-7-26 14:11

同时这也包含了&nbsp;分时处理&nbsp;&nbsp;的思想https://bbs.21ic.com/upfiles/img/20097/200972614753945.jpg

古道热肠 发表于 2009-7-26 14:26

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

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

程序匠人 发表于 2009-7-26 14:35

需要100ms吗?

会不会有点显得迟钝?

戒指320 发表于 2009-7-26 14:42

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

myfaith 发表于 2009-7-26 15:32

低电平检测100ms

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

oldli 发表于 2009-7-26 16:06

延时是必须的

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

戒指320 发表于 2009-7-26 16:23

O

请大家不要再对这个100ms发起讨论,前面说过这个可以调整。还有,有的情况下是不需要检测按键放开的。<br /><br />七楼大哥&nbsp;说用其他程序段代替延时程序也可取,关键这个代替延时的程序段每次执行所花费的时间固定吗?<br />&nbsp;我的意思是用&nbsp;时基&nbsp;来计时&nbsp;&nbsp;,设定一个变量&nbsp;cnt&nbsp;&nbsp;假如程序的主时基是4ms的话&nbsp;当检测到按键按下的时候&nbsp;inc&nbsp;cnt&nbsp;&nbsp;下一个回圈&nbsp;再检测按键,如果还按下的话,cnt&nbsp;再加一&nbsp;,当加到某个值的时候&nbsp;可以认为&nbsp;按键确实按下了这期间如果检测到又一次没按下,则clr&nbsp;cnt&nbsp;重新开始。如果取cnt=10&nbsp;则消抖时间是10*4=40ms<br /><br />贴出小弟的一段程序,<br />时基是2ms<br />key_scan:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,#01110000b&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;&nbsp;&nbsp;&nbsp;p0,a<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,#01111000b<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;p0ur,a<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,#10000000b<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;p0m,a<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,#00000111b<br />&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;&nbsp;&nbsp;&nbsp;p4,a<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;p4ur,a<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,#00000000b&nbsp;&nbsp;&nbsp;&nbsp;;com3输入,关led<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;p4m,a<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;$+1<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;$+1<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;$+1<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,p4<br />&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;&nbsp;&nbsp;&nbsp;a,#00000111b<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;new_key,a<br />&nbsp;&nbsp;&nbsp;&nbsp;bclr&nbsp;&nbsp;&nbsp;&nbsp;fc<br />&nbsp;&nbsp;&nbsp;&nbsp;rlcm&nbsp;&nbsp;&nbsp;&nbsp;new_key<br />&nbsp;&nbsp;&nbsp;&nbsp;rlcm&nbsp;&nbsp;&nbsp;&nbsp;new_key<br />&nbsp;&nbsp;&nbsp;&nbsp;rlcm&nbsp;&nbsp;&nbsp;&nbsp;new_key<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,p0<br />&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;&nbsp;&nbsp;&nbsp;a,#01110000b<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;r,a<br />&nbsp;&nbsp;&nbsp;&nbsp;bclr&nbsp;&nbsp;&nbsp;&nbsp;fc<br />&nbsp;&nbsp;&nbsp;&nbsp;rrcm&nbsp;&nbsp;&nbsp;&nbsp;r<br />&nbsp;&nbsp;&nbsp;&nbsp;rrcm&nbsp;&nbsp;&nbsp;&nbsp;r<br />&nbsp;&nbsp;&nbsp;&nbsp;rrcm&nbsp;&nbsp;&nbsp;&nbsp;r<br />&nbsp;&nbsp;&nbsp;&nbsp;rrcm&nbsp;&nbsp;&nbsp;&nbsp;r<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,r<br />&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;&nbsp;&nbsp;&nbsp;new_key,a;00******=00seg6&nbsp;seg5&nbsp;seg4&nbsp;seg3&nbsp;seg2&nbsp;seg1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;bts0&nbsp;&nbsp;&nbsp;&nbsp;f_key_rel&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan10&nbsp;&nbsp;&nbsp;&nbsp;;检测放键<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan20&nbsp;&nbsp;&nbsp;&nbsp;;检测按键<br />key_scan10:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,new_key<br />&nbsp;&nbsp;&nbsp;&nbsp;cmprs&nbsp;&nbsp;&nbsp;&nbsp;a,#00111111b<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan30<br />&nbsp;&nbsp;&nbsp;&nbsp;incms&nbsp;&nbsp;&nbsp;&nbsp;key_cnt<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,key_cnt<br />&nbsp;&nbsp;&nbsp;&nbsp;cmprs&nbsp;&nbsp;&nbsp;&nbsp;a,#15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;30ms<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan90<br />&nbsp;&nbsp;&nbsp;&nbsp;bclr&nbsp;&nbsp;&nbsp;&nbsp;f_key_rel<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan30<br />key_scan20:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,new_key<br />&nbsp;&nbsp;&nbsp;&nbsp;cmprs&nbsp;&nbsp;&nbsp;&nbsp;a,old_key<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan21<br />&nbsp;&nbsp;&nbsp;&nbsp;incms&nbsp;&nbsp;&nbsp;&nbsp;key_cnt<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,key_cnt<br />&nbsp;&nbsp;&nbsp;&nbsp;cmprs&nbsp;&nbsp;&nbsp;&nbsp;a,#30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;60ms<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan90<br />&nbsp;&nbsp;&nbsp;&nbsp;clr&nbsp;&nbsp;&nbsp;&nbsp;key_cnt<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan40<br />key_scan21:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov_&nbsp;&nbsp;&nbsp;&nbsp;old_key,new_key<br />key_scan30:<br />&nbsp;&nbsp;&nbsp;&nbsp;clr&nbsp;&nbsp;&nbsp;&nbsp;key_cnt<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan90<br />key_scan40:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov&nbsp;&nbsp;&nbsp;&nbsp;a,new_key&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;cje&nbsp;&nbsp;&nbsp;&nbsp;a,#00111111b,key_scan90&nbsp;&nbsp;&nbsp;&nbsp;;无键按下不作处理<br />&nbsp;&nbsp;&nbsp;&nbsp;cje&nbsp;&nbsp;&nbsp;&nbsp;a,#00111110b,key_scan41<br />&nbsp;&nbsp;&nbsp;&nbsp;cje&nbsp;&nbsp;&nbsp;&nbsp;a,#00111101b,key_scan42<br />&nbsp;&nbsp;&nbsp;&nbsp;cje&nbsp;&nbsp;&nbsp;&nbsp;a,#00111011b,key_scan43<br />&nbsp;&nbsp;&nbsp;&nbsp;cje&nbsp;&nbsp;&nbsp;&nbsp;a,#00110111b,key_scan44<br />&nbsp;&nbsp;&nbsp;&nbsp;cje&nbsp;&nbsp;&nbsp;&nbsp;a,#00101111b,key_scan45<br />&nbsp;&nbsp;&nbsp;&nbsp;cje&nbsp;&nbsp;&nbsp;&nbsp;a,#00011111b,key_scan46<br />&nbsp;&nbsp;&nbsp;&nbsp;cje&nbsp;&nbsp;&nbsp;&nbsp;a,#00001111b,key_scan47&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan90&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />key_scan41:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov_&nbsp;&nbsp;&nbsp;&nbsp;event_buf,#1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;POWER键键值1<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan80<br />key_scan42:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov_&nbsp;&nbsp;&nbsp;&nbsp;event_buf,#2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;osc键键值2<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan80<br />key_scan43:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov_&nbsp;&nbsp;&nbsp;&nbsp;event_buf,#3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;HI/LOW键键值3<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan80<br />key_scan44:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov_&nbsp;&nbsp;&nbsp;&nbsp;event_buf,#4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;timer键值4<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan80<br />key_scan45:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov_&nbsp;&nbsp;&nbsp;&nbsp;event_buf,#5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;+auto键键值5<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan80<br />key_scan46:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov_&nbsp;&nbsp;&nbsp;&nbsp;event_buf,#6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;-auto键键值6<br />&nbsp;&nbsp;&nbsp;&nbsp;jmp&nbsp;&nbsp;&nbsp;&nbsp;key_scan80<br />key_scan47:<br />&nbsp;&nbsp;&nbsp;&nbsp;mov_&nbsp;&nbsp;&nbsp;&nbsp;event_buf,#7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;+-auto同时键值7<br />key_scan80:<br />&nbsp;&nbsp;&nbsp;&nbsp;bset&nbsp;&nbsp;&nbsp;&nbsp;f_key_rel<br />&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;&nbsp;&nbsp;&nbsp;wrt_FIFO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;将键值写入event_FIFO<br />key_scan90:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret

gaohq 发表于 2009-7-26 17:40

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

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

ayb_ice 发表于 2009-7-26 18:05

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

lwd110 发表于 2009-7-26 18:10

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

hyg1984 发表于 2009-7-26 20:17

板凳

观看

tyw 发表于 2009-7-26 21:09

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

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

yewuyi 发表于 2009-7-26 21:26

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

呵呵。。。

程序匠人 发表于 2009-7-26 22:35

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

尽信书则不如无书

戒指320 发表于 2009-7-26 22:56

继续顶

iC921 发表于 2009-7-26 23:47

100ms太久,只争1ms

iC921 发表于 2009-7-26 23:49

现在的按键形式可丰富

s46410864 发表于 2009-7-27 08:19

延时长点不要紧

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

gaohq 发表于 2009-7-27 08:57

大侠

可以设键标志,用一个或数个工作程序段的运行本身作延时。这样就不会有停止等待<br />_______________________________________________________<br />这个是怎么搞的呢?
页: [1] 2 3 4 5 6 7
查看完整版本: 按键可有**了,能体现一个人的编程水平