找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 23521|回复: 98
打印 上一主题 下一主题
收起左侧

分享一下十几年我一直使用的按键处理方法

  [复制链接]
跳转到指定楼层
楼主
ID:57081 发表于 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占用,但我觉得时间和代码的质量更重要。

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

评分

参与人数 1黑币 +3 收起 理由
second1111 + 3 绝世好帖!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏9 分享淘帖 顶 踩1
回复

使用道具 举报

来自 2#
ID:57973 发表于 2014-5-16 10:52 | 只看该作者
看了下,跟我的有异曲同工之妙,其实个人感觉,用定时器产生一个15ms左右的时间,作为消抖使用,如果程序不是特别大,将按键扫描程序放入主循环还是不错的。大家应该都知道,程序中最好不要用延delay()函数的。
回复

使用道具 举报

来自 3#
ID:64089 发表于 2015-12-25 11:35 | 只看该作者
思维是非常好的,只是内容略显空洞,只是简单描述一下没有实例分析,基本上没有实用价值。
回复

使用道具 举报

来自 4#
ID:1064915 发表于 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占用,但我觉得时间和代码的质量更重要。
如果你跟我的思路相同,也遇见过这样的困惑,可以考虑我的按键扫描方法

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

5#
ID:58552 发表于 2014-1-5 10:46 | 只看该作者
谢谢楼主
回复

使用道具 举报

6#
ID:58502 发表于 2014-1-5 20:13 | 只看该作者
看看再说
回复

使用道具 举报

7#
ID:58269 发表于 2014-1-5 22:28 | 只看该作者
看看再说~!
回复

使用道具 举报

8#
ID:58227 发表于 2014-1-9 20:15 | 只看该作者
谢谢,高手出手,嘿嘿
回复

使用道具 举报

9#
ID:56665 发表于 2014-2-20 09:49 | 只看该作者
谢谢分享
回复

使用道具 举报

10#
ID:59202 发表于 2014-2-21 15:37 | 只看该作者
看看写的如何
回复

使用道具 举报

11#
ID:59231 发表于 2014-2-23 19:26 | 只看该作者
谢谢楼主
回复

使用道具 举报

12#
ID:59151 发表于 2014-2-24 22:21 | 只看该作者
收藏学习
回复

使用道具 举报

13#
ID:59151 发表于 2014-2-24 22:28 | 只看该作者
没看见楼主运用什么语句,只看见楼主文档里介绍他的方法,呵呵。
回复

使用道具 举报

14#
ID:60820 发表于 2014-4-18 09:19 | 只看该作者
真心不错,很好。
回复

使用道具 举报

15#
ID:59884 发表于 2014-4-23 23:52 | 只看该作者
谢谢楼主分享!
回复

使用道具 举报

16#
ID:61189 发表于 2014-4-27 21:34 | 只看该作者
谢谢楼主分享!
回复

使用道具 举报

17#
ID:55219 发表于 2014-4-28 19:45 | 只看该作者
谢谢分享!
回复

使用道具 举报

18#
ID:61227 发表于 2014-4-28 21:18 | 只看该作者
谢谢楼主慷慨,学习了!
回复

使用道具 举报

19#
ID:25058 发表于 2014-5-15 19:57 来自手机 | 只看该作者
看看如何写的
回复

使用道具 举报

20#
ID:57973 发表于 2014-5-16 10:46 | 只看该作者
楼主热心肠
回复

使用道具 举报

21#
ID:61913 发表于 2014-5-16 11:38 | 只看该作者
下来学习下. 谢谢先
回复

使用道具 举报

22#
ID:62769 发表于 2014-6-9 15:49 | 只看该作者
多谢楼主分享
回复

使用道具 举报

23#
ID:65877 发表于 2014-9-7 10:31 | 只看该作者
学习了。
回复

使用道具 举报

24#
ID:59611 发表于 2014-9-7 10:43 | 只看该作者
谢谢楼主分享  新人下来研究学习
回复

使用道具 举报

25#
ID:65341 发表于 2014-9-8 12:02 | 只看该作者
很好额   受教了
回复

使用道具 举报

26#
ID:66142 发表于 2014-9-14 20:18 | 只看该作者
谢谢.学习学习
回复

使用道具 举报

27#
ID:56814 发表于 2014-9-16 19:53 | 只看该作者
有个实例最好了
回复

使用道具 举报

28#
ID:64062 发表于 2014-10-5 01:25 | 只看该作者
留个记号,支持下
回复

使用道具 举报

29#
ID:65893 发表于 2014-10-5 20:28 | 只看该作者
参考下,自己总是搞不定按键处理
回复

使用道具 举报

30#
ID:64825 发表于 2014-10-8 18:28 | 只看该作者
没有给代码啊
回复

使用道具 举报

31#
ID:67310 发表于 2014-10-13 16:43 | 只看该作者
感谢分享啊啊  
回复

使用道具 举报

32#
ID:67312 发表于 2014-10-13 19:13 | 只看该作者
谢谢,先下载收藏
回复

使用道具 举报

33#
ID:67460 发表于 2014-10-17 09:02 | 只看该作者
谢谢楼主。
回复

使用道具 举报

34#
ID:67598 发表于 2014-10-18 21:02 | 只看该作者
感谢。。。。
回复

使用道具 举报

35#
ID:67235 发表于 2014-10-20 16:48 | 只看该作者
学习学习
回复

使用道具 举报

36#
ID:67573 发表于 2014-10-20 19:30 | 只看该作者
谢谢楼主
回复

使用道具 举报

37#
ID:66501 发表于 2014-10-24 14:11 | 只看该作者
掘墓高手,专挖古墓,一挖一个坑,坑坑见墓。。
回复

使用道具 举报

38#
ID:64336 发表于 2014-10-29 14:22 | 只看该作者
看看再说
回复

使用道具 举报

39#
ID:68356 发表于 2014-11-5 12:29 | 只看该作者
下载了,看看
回复

使用道具 举报

40#
ID:53925 发表于 2014-11-7 11:07 | 只看该作者
谢谢楼主
回复

使用道具 举报

41#
ID:59400 发表于 2014-11-9 13:19 来自手机 | 只看该作者
谢谢分享
回复

使用道具 举报

42#
ID:68583 发表于 2014-11-9 20:04 | 只看该作者
一直在找这方面的资料
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表