找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 86232|回复: 241
收起左侧

[分享]分享一下我用了十几年的按键扫描方法

  [复制链接]
ID:51941 发表于 2013-7-22 11:43 | 显示全部楼层 |阅读模式
看见大家发了那么多按键的处理方法,我也发一个。

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

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

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

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

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

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

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

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

我摘录了与按键相关的部分,如果有疑问,欢迎通过邮件或QQ沟通。


key.rar

1.23 KB, 下载次数: 1696

按键处理

评分

参与人数 12黑币 +84 收起 理由
770632741 + 5 很给力!
zzffw + 5 很给力!
荒谬的真理 + 5 绝世好帖!
zxc562 + 5 共享资料的黑币奖励!
wangjunwu1995 + 5 22223
sunlei058378 + 15
archerelf + 2 很给力!
init() + 5 很给力!
一毛零logo + 5 说的很吸引人,感觉应该不错
absflash + 15 很给力!
YJGG + 12 赞一个!
遥远716 + 5 很给力!

查看全部评分

回复

使用道具 举报

ID:421260 发表于 2024-10-23 08:28 | 显示全部楼层
最大缺点,采用了中断
回复

使用道具 举报

ID:232619 发表于 2024-10-22 23:37 | 显示全部楼层

感谢楼主分享!!!!!!!
回复

使用道具 举报

ID:1128165 发表于 2024-10-21 15:49 | 显示全部楼层

貌似不错的样子。。。
回复

使用道具 举报

ID:1133909 发表于 2024-10-17 15:03 | 显示全部楼层
刚入门,正好学习一下先辈的经验
回复

使用道具 举报

ID:1008703 发表于 2022-3-7 11:41 | 显示全部楼层
进来学习一下,讲的非常仔细,谢谢楼主分享
回复

使用道具 举报

ID:702749 发表于 2022-3-4 10:47 | 显示全部楼层
小白帆 发表于 2018-5-2 08:49
楼主请问你的这段代码是什么意思?

bdata可寻址
回复

使用道具 举报

ID:928738 发表于 2022-2-25 10:10 | 显示全部楼层
                        if(gucKeyOkTimer>T_100MS)
                        {
                                gfOkPressing=1;
                                if(gfOkPressing==0)
                                        gfOkNeedAck=1;

                        }
这个gfOkPressing==0,永远达不到条件。哪里忘了修改了?
回复

使用道具 举报

ID:71535 发表于 2020-2-15 09:42 | 显示全部楼层

闭关期间,好好学习,天天进步。
回复

使用道具 举报

ID:693302 发表于 2020-2-14 19:02 | 显示全部楼层

感谢楼主分享,学习了!
回复

使用道具 举报

ID:64253 发表于 2020-2-14 09:29 | 显示全部楼层
先下载了,在研究学习
回复

使用道具 举报

ID:690948 发表于 2020-2-13 11:26 来自触屏版 | 显示全部楼层
高手在民间
回复

使用道具 举报

ID:465279 发表于 2020-2-12 22:35 | 显示全部楼层
就是来学习的,感谢你的分享。
回复

使用道具 举报

ID:378732 发表于 2019-11-5 15:33 | 显示全部楼层
学习一下
回复

使用道具 举报

ID:636013 发表于 2019-11-5 14:47 | 显示全部楼层
好东西好东西
回复

使用道具 举报

ID:61950 发表于 2019-9-4 11:00 来自触屏版 | 显示全部楼层
昨晚研究了一晚,还是没太懂
回复

使用道具 举报

ID:207133 发表于 2019-9-4 09:41 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:385637 发表于 2019-9-4 08:35 | 显示全部楼层
好资料,谢谢分享
回复

使用道具 举报

ID:607060 发表于 2019-9-3 19:17 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:468431 发表于 2019-4-16 09:00 | 显示全部楼层
做项目正好遇到了这个问题,及时雨一般看到这帖子,谢谢楼主分享!!!
回复

使用道具 举报

ID:337487 发表于 2019-3-19 19:58 | 显示全部楼层
好方法可以学习一下,谢谢分享
回复

使用道具 举报

ID:477688 发表于 2019-2-26 13:30 | 显示全部楼层

感谢楼主分享!!!
回复

使用道具 举报

ID:116773 发表于 2018-12-17 20:41 | 显示全部楼层
下载学习,尚未看明白。
回复

使用道具 举报

ID:448238 发表于 2018-12-17 18:36 | 显示全部楼层
想下载下了看看~
回复

使用道具 举报

ID:118735 发表于 2018-7-27 17:00 | 显示全部楼层
感谢楼主分享
回复

使用道具 举报

ID:377927 发表于 2018-7-23 15:12 | 显示全部楼层
学习一下,谢谢
回复

使用道具 举报

ID:64253 发表于 2018-7-23 14:41 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:110278 发表于 2018-7-19 15:08 | 显示全部楼层
讲解的很详细,必须支持一个。
回复

使用道具 举报

ID:357149 发表于 2018-7-18 21:06 | 显示全部楼层
谢谢楼主分享,这个东西简洁快速十分有用
回复

使用道具 举报

ID:67705 发表于 2018-5-26 12:49 | 显示全部楼层
这个东东绝对值得一看。
回复

使用道具 举报

ID:67705 发表于 2018-5-26 12:48 | 显示全部楼层
这个东东绝对值得一看。
回复

使用道具 举报

ID:145032 发表于 2018-5-26 12:34 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:104760 发表于 2018-5-25 09:08 | 显示全部楼层
感谢楼主分享!!!!!!!!
回复

使用道具 举报

ID:331575 发表于 2018-5-23 22:31 | 显示全部楼层
刷新了我对防抖按键的写法  厉害
回复

使用道具 举报

ID:331575 发表于 2018-5-23 07:24 来自触屏版 | 显示全部楼层
谢谢分享思路
回复

使用道具 举报

ID:293762 发表于 2018-5-20 22:28 | 显示全部楼层
谢谢分享!
回复

使用道具 举报

ID:288202 发表于 2018-5-2 08:49 | 显示全部楼层
  1. unsigned char bdata        gucKeyFlag1;   
  2. sbit gfOkPressing         =gucKeyFlag1^0;
  3. sbit gfOkNeedAck        =gucKeyFlag1^1;  
  4. sbit gfUpPressing         =gucKeyFlag1^2;
  5. sbit gfUpNeedAck        =gucKeyFlag1^3;
  6. sbit gfDownPressing         =gucKeyFlag1^4;
  7. sbit gfDownNeedAck        =gucKeyFlag1^5;
  8. sbit gfCancelPressing         =gucKeyFlag1^6;
  9. sbit gfCancelNeedAck        =gucKeyFlag1^7;                                      
  10. unsigned char bdata        gucKeyFlag2;      
  11. sbit gfMenuPressing         =gucKeyFlag2^0;
  12. sbit gfMenuNeedAck        =gucKeyFlag2^1;
  13. sbit gfONOFFPressing         =gucKeyFlag2^2;
  14. sbit gfONOFFNeedAck        =gucKeyFlag2^3;
复制代码



楼主请问你的这段代码是什么意思?
回复

使用道具 举报

ID:66287 发表于 2018-3-7 10:30 | 显示全部楼层
非常好的编程思路
回复

使用道具 举报

ID:76133 发表于 2018-3-6 20:50 | 显示全部楼层
感谢楼主分享!!!!
回复

使用道具 举报

ID:67838 发表于 2018-3-6 16:27 | 显示全部楼层
看看高级的程序
回复

使用道具 举报

ID:287564 发表于 2018-3-6 13:26 | 显示全部楼层
感觉很给力,谢谢分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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