标题: 分享一下十几年我一直使用的按键处理方法 [打印本页]

作者: 中科网    时间: 2013-11-4 15:33
标题: 分享一下十几年我一直使用的按键处理方法
分享一下十几年我一直使用的按键处理方法
看见大家发了那么多按键的处理方法,我也发一个。

刚参加工作的时候,对比学校里和同事的按键处理函数,发现总是不尽如人意,
有以下几点:
1. 消抖复杂,效率低。很多人直接在电平判断后使用delay()函数,进行消抖,
耽误时间;有人在按键电平中断中消抖,导致其他的中断,比如串口、定时等
反应很慢,不适合做实时系统;
2. 特殊功能按键的处理麻烦。使用简单电平判断的按键扫描,在需要长按响应、
复合按键响应、复合按键长按响应的时候,需要增加很多的标志位,反复使用
if..else判断,有时候把自个都搞乱了。
3. 不便于移植和修改。使用以上两点编写的函数,如果用在直接端口按键上的,
那么在行列扫描按键的时候,就很难适应。导致每个项目都要更改一次。

想了很久之后,我结合PC的键盘处理方法,编写了自己的按键函数,经过几次修改,
定了下来。这十几年来,一直在用,方便移植,而且比较清晰。
——至少我自己这么觉得。

它有以下几个特点:
1. 按键扫描和取值分开。
    在中断中(一般10ms),反复调用keyScan()进行按键扫描(包括消抖)。
    消抖之后的按键值不返回,作为消息放到全局变量中;
    在需要判断的地方使用getKeyValue()获取当前的键值,进行处理。

2. 每一个按键,都有单独的标志位和计时变量。
    消抖计时:
    如果按键按下,每调用一次10ms中断,gucKeyOkTimer增加;
    gucKeyOkTimer超过消抖的阀值(我一般10次,即100ms),则确认有按键了。
    任何一次扫描到按键没有按下,gucKeyOkTimer清空;

    标志位:
    如果一直按着(通过按键电平判断),会有gfOkPressing;
    如果按下过一次,需要响应,会有gfOkNeedAck;

    复合按键的响应:
    因为每个按键,包括复合按键都有自己的标志位和计时变量,可以跟物理按键的
    处理方法相同。只是消抖的条件,不是电平的判断,而是物理按键的pressing标志。

3. 我没有使用怪癖诡异的编程方法。有很多取巧的方法可使实现按键的扫描,甚至有
人写了三行代码就实现消抖。——我个人不喜欢这样的程序风格。我喜欢思路清晰的编程方法,
易于维护和移植。当然代价就是多了一些ROM和RAM占用,但我觉得时间和代码的质量更重要。

如果你跟我的思路相同,也遇见过这样的困惑,可以考虑我的按键扫描方法

作者: whiskycheung    时间: 2014-1-5 10:46
谢谢楼主
作者: liaolinhui    时间: 2014-1-5 20:13
看看再说
作者: 雕亦倾心    时间: 2014-1-5 22:28
看看再说~!
作者: admin2013    时间: 2014-1-9 20:15
谢谢,高手出手,嘿嘿
作者: m182892    时间: 2014-2-20 09:49
谢谢分享
作者: xxxevery    时间: 2014-2-21 15:37
看看写的如何
作者: sdlkfjlkj    时间: 2014-2-23 19:26
谢谢楼主
作者: wgh008    时间: 2014-2-24 22:21
收藏学习
作者: wgh008    时间: 2014-2-24 22:28
没看见楼主运用什么语句,只看见楼主文档里介绍他的方法,呵呵。
作者: jingsheng_cao    时间: 2014-4-18 09:19
真心不错,很好。
作者: 盛世游龙    时间: 2014-4-23 23:52
谢谢楼主分享!
作者: zrl    时间: 2014-4-27 21:34
谢谢楼主分享!
作者: yxz1140    时间: 2014-4-28 19:45
谢谢分享!
作者: a651738901    时间: 2014-4-28 21:18
谢谢楼主慷慨,学习了!
作者: liang1981    时间: 2014-5-15 19:57
看看如何写的
作者: xzxlove    时间: 2014-5-16 10:46
楼主热心肠
作者: xzxlove    时间: 2014-5-16 10:52
看了下,跟我的有异曲同工之妙,其实个人感觉,用定时器产生一个15ms左右的时间,作为消抖使用,如果程序不是特别大,将按键扫描程序放入主循环还是不错的。大家应该都知道,程序中最好不要用延delay()函数的。
作者: szsurfing    时间: 2014-5-16 11:38
下来学习下. 谢谢先
作者: 飓风de菜菜    时间: 2014-6-9 15:49
多谢楼主分享
作者: zmkgzsz2014    时间: 2014-9-7 10:31
学习了。
作者: 平安2006916    时间: 2014-9-7 10:43
谢谢楼主分享  新人下来研究学习
作者: lzzgg834483370    时间: 2014-9-8 12:02
很好额   受教了
作者: mcaeg    时间: 2014-9-14 20:18
谢谢.学习学习
作者: yzmmdy    时间: 2014-9-16 19:53
有个实例最好了
作者: 一人心    时间: 2014-10-5 01:25
留个记号,支持下
作者: yc21    时间: 2014-10-5 20:28
参考下,自己总是搞不定按键处理
作者: qzsulin    时间: 2014-10-8 18:28
没有给代码啊
作者: 永远18    时间: 2014-10-13 16:43
感谢分享啊啊  
作者: jinanyuanyue    时间: 2014-10-13 19:13
谢谢,先下载收藏
作者: zsshd    时间: 2014-10-17 09:02
谢谢楼主。
作者: ganchao945    时间: 2014-10-18 21:02
感谢。。。。
作者: tjj163    时间: 2014-10-20 16:48
学习学习
作者: blj178    时间: 2014-10-20 19:30
谢谢楼主
作者: hjlost    时间: 2014-10-24 14:11
掘墓高手,专挖古墓,一挖一个坑,坑坑见墓。。

作者: 北漂的二极管    时间: 2014-10-29 14:22
看看再说
作者: xiuyueyuan2013    时间: 2014-11-5 12:29
下载了,看看
作者: 心宇(语)    时间: 2014-11-7 11:07
谢谢楼主
作者: 娃娃鱼翅膀    时间: 2014-11-9 13:19
谢谢分享
作者: lishaoping1984    时间: 2014-11-9 20:04
一直在找这方面的资料
作者: liwanxi    时间: 2014-11-9 21:05
没钱下,收下先.
作者: 本本12    时间: 2014-11-14 15:16
看看再说
作者: zgs660429    时间: 2014-11-18 11:11
不错,学习一下。
作者: dzljp    时间: 2014-11-19 21:47
谢谢楼主分享
作者: 2796277453    时间: 2014-11-20 22:10
谢谢楼主。。
作者: zjf110    时间: 2014-11-25 01:33
看看再说~!
作者: zjf110    时间: 2014-11-25 01:47
感谢楼主分享
作者: zsshd    时间: 2014-12-17 07:13
和大家一样,我一直在找按键处理方面的资料。特别感谢楼主的慷慨!谢谢!!
作者: xiao_yp2014    时间: 2014-12-17 08:21
没有代码呢?请上一个吧。
作者: zsshd    时间: 2014-12-17 11:13
根据楼主的方法,程序一直没有调试成功,主要自己入门短。大家有成功的吗?能再指点一二吗?
作者: zgs660429    时间: 2014-12-17 22:46
谢谢分享
作者: 中奥ol    时间: 2014-12-18 19:08
谢谢啦
作者: LN555    时间: 2014-12-20 12:00
这是个坑啊
作者: 唉丶芒果    时间: 2014-12-20 15:16
好用麽。试试
作者: ywd683    时间: 2015-1-2 09:14
谢谢,先下载收藏
作者: qq704661078    时间: 2015-1-31 19:09
谢谢楼主分享!!!
作者: fontex    时间: 2015-2-2 13:38
十分感谢!
作者: w5201314123    时间: 2015-2-6 17:09
看看怎么做的
作者: AOP    时间: 2015-2-8 17:41
看看再说............
作者: naijiu    时间: 2015-2-9 04:05
谢谢楼主分享,学习了,,,
作者: ding1995    时间: 2015-2-10 21:43
我也说一句什么啊啦啦啦
作者: muzimuzi    时间: 2015-2-11 04:35
应该会挺不错的吧
作者: 正本清源    时间: 2015-2-11 06:49
谢谢分享!
作者: qpx770223    时间: 2015-2-13 18:46

支持顶一下
作者: qpx770223    时间: 2015-2-13 18:46

支持顶一下
作者: zoomhan    时间: 2015-2-15 13:15

看看再说~!
作者: ydmxyz    时间: 2015-2-20 17:37
谢谢楼主
作者: wangyifan    时间: 2015-2-22 17:50
下载研究学习一下,谢谢。
作者: meilidianzhi    时间: 2015-2-23 22:09
谢谢你
作者: w2015x    时间: 2015-3-5 18:02
看看写的如何
作者: znddcc    时间: 2015-4-10 11:17
学习下
作者: hlywhp    时间: 2015-4-27 21:52
这个实用,谢了
作者: kmtbm    时间: 2015-7-19 12:26

已经下载了,不错不错
作者: 段水青云    时间: 2015-7-19 19:50
好好好
作者: 段水青云    时间: 2015-7-19 19:50
很不错不错
作者: 绿源学习者    时间: 2015-7-20 12:25
不知道怎么样,下载看看在说

作者: basic_yuxw    时间: 2015-7-22 07:24
楼主能不能给个程序参考下
作者: bhjyqjs    时间: 2015-7-22 10:56
挖墓高手,这种东西,直接贴出就是了
作者: dangbingjoe    时间: 2015-7-22 11:09
挺好的不错的啊
作者: abc123194    时间: 2015-7-22 14:27
我看看,参考一下;没程序看不明白
作者: nyzgj    时间: 2015-8-28 23:54
谢啦              
作者: sleepinbed    时间: 2015-8-29 01:27
好东西  谢谢楼主的无私奉献!
作者: jiakuo25    时间: 2015-8-29 16:01
看过了,思路不错 顶一下
作者: bhjyqjs    时间: 2015-8-31 08:17
方法还是很好的
作者: jnu1214    时间: 2015-12-5 17:56
只是文字上简单介绍了下,没有代码的
作者: 永远的王同学    时间: 2015-12-25 01:15
好!实践出真知!
作者: bbxyzzj    时间: 2015-12-25 08:52

有个实例最好了,更有利于初学者。
作者: nsj21n    时间: 2015-12-25 11:35
思维是非常好的,只是内容略显空洞,只是简单描述一下没有实例分析,基本上没有实用价值。
作者: 初学者的L    时间: 2015-12-26 10:48
谢谢楼主。
作者: 雪玉寐影    时间: 2015-12-27 14:53
学习借鉴一下
作者: 小鑫好菜    时间: 2016-11-15 23:03
看看下,谢谢楼主分享                                                                                 
作者: 重楼之巅    时间: 2016-11-15 23:35
学习一下,谢谢楼主
作者: xht9951    时间: 2016-11-16 18:00
刚刚注册,下载不了,不知道和宋学松老师的有什么区别
作者: linbai    时间: 2018-11-27 20:26
东西挺好的,
作者: amos_machine    时间: 2024-7-14 16:50
下载,打开EXEL文件错误

作者: joyb    时间: 2024-7-15 14:36
nsj21n 发表于 2015-12-25 11:35
思维是非常好的,只是内容略显空洞,只是简单描述一下没有实例分析,基本上没有实用价值。

分享一下十几年我一直使用的按键处理方法
看见大家发了那么多按键的处理方法,我也发一个。
刚参加工作的时候,对比学校里和同事的按键处理函数,发现总是不尽如人意,有以下几点:
1. 消抖复杂,效率低。很多人直接在电平判断后使用delay()函数,进行消抖,耽误时间;有人在按键电平中断中消抖,导致其他的中断,比如串口、定时等反应很慢,不适合做实时系统;
2. 特殊功能按键的处理麻烦。使用简单电平判断的按键扫描,在需要长按响应、复合按键响应、复合按键长按响应的时候,需要增加很多的标志位,反复使用if..else判断,有时候把自个都搞乱了。
3. 不便于移植和修改。使用以上两点编写的函数,如果用在直接端口按键上的,那么在行列扫描按键的时候,就很难适应。导致每个项目都要更改一次。

想了很久之后,我结合PC的键盘处理方法,编写了自己的按键函数,经过几次修改,定了下来。这十几年来,一直在用,方便移植,而且比较清晰。
——至少我自己这么觉得。

它有以下几个特点:
1. 按键扫描和取值分开。
    在中断中(一般10ms),反复调用keyScan()进行按键扫描(包括消抖)。
    消抖之后的按键值不返回,作为消息放到全局变量中;
    在需要判断的地方使用getKeyValue()获取当前的键值,进行处理。

2. 每一个按键,都有单独的标志位和计时变量。
    消抖计时:
    如果按键按下,每调用一次10ms中断,gucKeyOkTimer增加;
    gucKeyOkTimer超过消抖的阀值(我一般10次,即100ms),则确认有按键了。
    任何一次扫描到按键没有按下,gucKeyOkTimer清空;

    标志位:
    如果一直按着(通过按键电平判断),会有gfOkPressing;
    如果按下过一次,需要响应,会有gfOkNeedAck;

复合按键的响应:
因为每个按键,包括复合按键都有自己的标志位和计时变量,可以跟物理按键的处理方法相同。只是消抖的条件,不是电平的判断,而是物理按键的pressing标志。
3. 我没有使用怪癖诡异的编程方法。有很多取巧的方法可使实现按键的扫描,甚至有人写了三行代码就实现消抖。——我个人不喜欢这样的程序风格。我喜欢思路清晰的编程方法,易于维护和移植。当然代价就是多了一些ROM和RAM占用,但我觉得时间和代码的质量更重要。
如果你跟我的思路相同,也遇见过这样的困惑,可以考虑我的按键扫描方法

作者: gzyanbo    时间: 2024-7-15 16:11
想知道运用的例程
作者: 巨人卡奥    时间: 2024-7-22 15:16
牛皮,十几年的经验
作者: csmjmcc    时间: 2024-7-30 10:57
没有源码?




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1