野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11266|回复: 27

多功能按键设计原理分析,单击,长按,双击各个击破

[复制链接]
发表于 2016-10-7 22:03:45 | 显示全部楼层 |阅读模式
  今天傍晚就去吃饭时,看到论坛里面有一个人分享了一个按键多功能设计的代码,无奈自己才疏学浅,看了没有看懂,于是就一怒之下,百度之,最后把他搞明白了,遂在这,分享给大家,希望能给大家一个帮助

回复

使用道具 举报

 楼主| 发表于 2016-10-7 22:03:46 | 显示全部楼层
点了一下保存草稿按钮,谁知就已经发出来了 ,那只能,另起一楼来说道说道了。
设计目标:
将按键PB0功能分成了三个:单击,双击,长按
当单击时,LED2亮,LED3/LED4灭
当长按时,LED3亮,LED2/LED4灭
当双击时,LED4亮,LED2/LED3灭

程序设计流程:
1、利用TIM2,产生一个10ms中断,10ms中断时间到,中断标志time_10ms_ok置位
2、在主函数里面,通过判断中断标志位if(time_10ms_ok),来对按键状态进行读取,记得读取完毕后,要将中断标志time_10ms_ok清零
3、按键状态读取函数key_read,来判断是单击还是双击,而key_driver来判断是短按键还是长按键,key_read需要调用key_driver来进行单击/双击的判断
4、对应按键的不同状态反应在不同led的明暗上

我感觉的难点在于:
短按键,长按键是怎么定义的,何为长,何又为短?这个需要考虑,在程序中,定义:按键时间<1s为短按键,按键时间>1s为长按键
单击和双击是怎么区分开的,定义两个相隔500ms以内的短按键为双击,如果两个单击的时间相隔大于500ms,就认为是两次单击,并且双击只仅限于两个短按键之间,如果一个短按键之后的500ms之内配上一个长按键,这不是双击,把他定义为单击。同样,一个长按键之后500ms之内配上一个短按键,这也不是双击,而是一个短按键。


程序已经在32开发板上跑过,功能可以实现,PB0入口的KEY按下时,为低电平,未按下时,为高电平,移植时有可能这里需要改,还要LED口这里需要改!在程序中有更加详细的注释,希望能给您带来帮助!

PS:以上只是个人的一点见解,有不对的地方,还望各位大神指点,谢谢了!















实验1 一键多功能实验.rar

3.39 MB, 下载次数: 375

回复 支持 反对

使用道具 举报

发表于 2016-10-8 08:45:50 | 显示全部楼层
研究生就是不一样
回复 支持 反对

使用道具 举报

发表于 2016-10-8 08:53:25 | 显示全部楼层
看看                        
回复 支持 反对

使用道具 举报

发表于 2016-10-8 08:54:22 | 显示全部楼层
如果在加一个连击呢,
回复 支持 反对

使用道具 举报

发表于 2016-10-8 08:57:02 | 显示全部楼层
下载学习~~~~~~~~~~
回复

使用道具 举报

发表于 2016-10-8 08:58:32 | 显示全部楼层
正好在学习有关按键扫描的程序,好东西收下哈,感谢楼主分享!
回复 支持 反对

使用道具 举报

发表于 2016-10-8 09:00:15 | 显示全部楼层
如果用查询的方式,不用中断来做呢
回复 支持 反对

使用道具 举报

发表于 2016-10-8 09:00:36 | 显示全部楼层
就是不一样
回复 支持 反对

使用道具 举报

发表于 2016-10-8 09:02:13 | 显示全部楼层
可以啊,一直是这种方案,不占CPU资源,不用消抖
回复 支持 反对

使用道具 举报

发表于 2016-10-8 09:09:15 | 显示全部楼层
smtudou 发表于 2016-10-7 22:03
点了一下保存草稿按钮,谁知就已经发出来了 ,那只能,另起一楼来说道说道了。
设计目标:
将按键PB0功能 ...

如果使用双击是不是意味着单击必须延时500ms再做判断
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-8 09:50:48 | 显示全部楼层
fire 发表于 2016-10-8 08:45
研究生就是不一样

距离火哥还差太远,还要好好努力~~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-8 09:51:16 | 显示全部楼层
Hankin 发表于 2016-10-8 08:54
如果在加一个连击呢,

是要3连击吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-8 09:51:53 | 显示全部楼层
惟爱你 发表于 2016-10-8 08:58
正好在学习有关按键扫描的程序,好东西收下哈,感谢楼主分享!

相互帮助哈~~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-8 09:55:33 | 显示全部楼层
yy915174852 发表于 2016-10-8 09:00
如果用查询的方式,不用中断来做呢

这里的中断就是一个定时,一定时间去扫描下按键,应该可以放在while大循环里面,然后在while里稍微加一个延时delay_ms(10)来做~~你可以试下
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-8 09:57:42 | 显示全部楼层
cancore 发表于 2016-10-8 09:09
如果使用双击是不是意味着单击必须延时500ms再做判断

对!这样反应会变得慢一些~~但可以将这个时间缩短来使它对单击的反应更快些
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-8 09:58:59 | 显示全部楼层
怪番茄 发表于 2016-10-8 09:02
可以啊,一直是这种方案,不占CPU资源,不用消抖

这都是参考前辈们的智慧,我要好好地向你们学习
回复 支持 反对

使用道具 举报

发表于 2016-10-8 10:33:51 | 显示全部楼层

是按住按键不松开,数码管上的数值就以一定的速度一直往上递增,,,很多产品都有这种连加连减功能的
双击功能倒是不怎么常用
回复 支持 反对

使用道具 举报

发表于 2016-10-8 11:33:20 | 显示全部楼层
感谢楼主,看懂了。
分享一下我个人理解,
        分析:
        按键每10ms扫描一次,扫描按下是否按下,如果开始第一个10ms到了,按键按下,则将标志位key_state = 1,key_return = 0;
        第二个10ms到了,按键还是按下的,置key_state = 2, 此时key_retuen 还是 = 0。
        第三个10ms到了,判断按键是不是已经松开了,是。返回 key_return = S_key=1,
                                                                                                                        还没有松开 将key_time 自加 到100,每10ms 自加一次,总得时间是10ms*100= 1s;
                                                                                                                        1s钟到了, key_return  = L_key= 2,如果1s钟时间没有到,则返回 的是 0 ;
        所以,只有到了第三个10ms key_driver()返回值才不为0 为S_key 和 L_key
       
        在switch 中判断,第3个10ms 到达的时候才有效。key_temp 的值不为0. 如果是单击S_key 则置标志位key_m 为 key_state_1 下一次在
        判断是不是双击D_key,
        如果不时单击,S_key 则保持原来的返回值 (L_key)长按
回复 支持 反对

使用道具 举报

发表于 2016-10-8 11:44:27 | 显示全部楼层
厉害,,,学习了。。。
回复 支持 反对

使用道具 举报

发表于 2016-10-8 14:01:21 | 显示全部楼层
挺好的 。。。学习了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-8 15:20:23 | 显示全部楼层
Hankin 发表于 2016-10-8 10:33
是按住按键不松开,数码管上的数值就以一定的速度一直往上递增,,,很多产品都有这种连加连减功能的
双 ...

这个功能已经实现,在判断他是一个长按键后,将长按键按下标志L_flag置位,然后在等待长按键释放后,L_flag置零
接下来就是在main函数while大循环中,对这个标志进行判断,                       
                               if(L_flag)
                                {
                                        TIM_Cmd(TIM3, ENABLE);
                                        GUI_sprintf_chartodec(200,100,sec,RED,GBLUE);
                                }
                                else
                                {
                                        TIM_Cmd(TIM3, DISABLE);
                                        GUI_sprintf_chartodec(200,200,sec,RED,GBLUE);
                                }
当L_flag=1时,打开TIM3,(TIM3设置为一个1s的定时器),这时将秒值在液晶上实时显示
当L_flag=0时,关闭TIM3,这时秒值不再刷新,


程序,我在下楼贴出了,有不对的地方,还求指点。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-8 15:23:18 | 显示全部楼层
添加了一个长按,数值增加的功能

实验1 一键多功能实验(添加了一个长按,数值增加的功能).rar

3.65 MB, 下载次数: 184

回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-8 15:31:09 | 显示全部楼层
xdh873939316 发表于 2016-10-8 11:33
感谢楼主,看懂了。
分享一下我个人理解,
        分析:

嗯!!是这个思路来的,一起努力加油啊~~~
回复 支持 反对

使用道具 举报

发表于 2017-5-10 15:32:40 | 显示全部楼层
mark.........
回复

使用道具 举报

发表于 2017-5-11 09:54:14 | 显示全部楼层
Hankin 发表于 2016-10-8 10:33
是按住按键不松开,数码管上的数值就以一定的速度一直往上递增,,,很多产品都有这种连加连减功能的
双 ...

单击有效的时候判断按键是否松开,如果未松开,就每隔一段时间将单击置为有效,直到按键松开,这样单击就可以当连击用了。
回复 支持 反对

使用道具 举报

发表于 2017-5-11 09:56:26 | 显示全部楼层
我也在论坛发了一个,不过有一个小BUG,修复了的没发出来,既然楼主又发了就不再更新了。讲得挺详细的,不错,挺你。我的就没啥文字解释
回复 支持 反对

使用道具 举报

发表于 2017-5-26 12:06:38 | 显示全部楼层
蛮好的 思路清晰
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-6-28 11:44 , Processed in 0.042590 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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