怎样实现单片机按键双按、长按识别功能?

时间:2022-11-30 18:00:51
我用C51编程设计一个4键小键盘,想让程序判断出按键是否为双击、长按。 
在识别双击部分,我想设两次击键的间隔时间为0.5s,但不知道如何设置定时器。 

请高手指教,我是新手,请讲解详细一些,万分感谢!

14 个解决方案

#1


LZ,0.5S,有这么设置吗?

貌似很难实现啊

我个人想法是让每次击键都产生一个信号发送给C51,然后在做后续处理

#2


定时器?在中断中判断?

#3


瞎说的,嘿嘿

#4


我的意思是设定一个按键双击的时间间隔0.5s,此次按键与上一次按键的时间间隔小于0.5s则判断为双击,大于0.5s则判断为单击。那是不是应该启动一个定时器来对按键释放的时间计时呢?

#5


双击应该比0.5秒要短,最好LZ还是弄一个测试程序,让用户自己设定吧

单片机在做这个上要郁闷哈,咱们的键的那个抖动,嘿嘿

好运...

#6


使用状态机。
以下以一个按键A为例:键值为A_Key(每一次收到A_Key表示按键A被按下一次).
假设每50ms扫描一次。

状态           意义
-------------------------------------
Idel  ---- 按键没有按下(初始状态)
KDowm ---- 按键按下
KUp   ---- 按键弹起
-------------------------------------
         ______________________
         |                     |
         |                     |
         v              A_Key  |
       Idel ----> KDowm ----> KUp
                  ^   |
                  |___|
                  A_Key

--------------------------------------
看得懂就看吧,看不懂就算了。。。。

#7


使用状态机。
以下以一个按键A为例:键值为A_Key(每一次收到A_Key表示按键A被按下一次).
假设每50ms扫描一次。

状态           意义
-------------------------------------
Idel  ---- 按键没有按下(初始状态)
KDowm ---- 按键按下
KUp   ---- 按键弹起
-------------------------------------
#########______________________
#########|                     |
#########|                     |
#########v              A_Key  |
########Idel ----> KDowm ----> KUp
###################^   |
###################|___|
###################A_Key

--------------------------------------
看得懂就看吧,看不懂就算了。。。。
格式问题。。。

#8


使用状态机。
以下以一个按键A为例:键值为A_Key(每一次收到A_Key表示按键A被按下一次).
假设每50ms扫描一次。

状态           意义
-------------------------------------
Idel  ---- 按键没有按下(初始状态)
KDowm ---- 按键按下
KUp   ---- 按键弹起
-------------------------------------
#########______________________
#########|#####################|
#########|#####################|
#########v##############A_Key##|
########Idel ----> KDowm ----> KUp
###################^###|
###################|###|
###################A_Key

--------------------------------------
看得懂就看吧,看不懂就算了。。。。
格式问题,把#号去掉看。。。

#9




使用状态机。
以下以一个按键A为例:键值为A_Key(每一次收到A_Key表示按键A被按下一次).
假设每50ms扫描一次。

状态           意义
-------------------------------------
Idel  ---- 按键没有按下(初始状态)
KDowm ---- 按键按下
KUp   ---- 按键弹起
-------------------------------------

         ______________________
         |                     |
         v              A_Key  |
        Idel ----> KDowm ----> KUp
                   ^   |
                   |___|
                   A_Key

--------------------------------------
看得懂就看吧,看不懂就算了。。。。
格式问题,把#号去掉看。。。

#10


终于对头了,瀑布汗

#11


判断按键抬起,从按下到抬起为一次按键,记录这个状态,计数器开始工作,到检测到下一次按键或者计数超时计数器可以停止计数,认为单次按键

长按就是检测到按键按下开始计数,到额定时间按键如果保持按下状态就认为长按
用状态机来做比较好

#12


前几天做了个抗抖  采样N次判断是否稳定
效果还不错,,就是浪费点资源  要一个定时器

#13


codehat 辛苦了

#14


顶11楼,那Codehat 说跟不说一个样,不看也罢

#1


LZ,0.5S,有这么设置吗?

貌似很难实现啊

我个人想法是让每次击键都产生一个信号发送给C51,然后在做后续处理

#2


定时器?在中断中判断?

#3


瞎说的,嘿嘿

#4


我的意思是设定一个按键双击的时间间隔0.5s,此次按键与上一次按键的时间间隔小于0.5s则判断为双击,大于0.5s则判断为单击。那是不是应该启动一个定时器来对按键释放的时间计时呢?

#5


双击应该比0.5秒要短,最好LZ还是弄一个测试程序,让用户自己设定吧

单片机在做这个上要郁闷哈,咱们的键的那个抖动,嘿嘿

好运...

#6


使用状态机。
以下以一个按键A为例:键值为A_Key(每一次收到A_Key表示按键A被按下一次).
假设每50ms扫描一次。

状态           意义
-------------------------------------
Idel  ---- 按键没有按下(初始状态)
KDowm ---- 按键按下
KUp   ---- 按键弹起
-------------------------------------
         ______________________
         |                     |
         |                     |
         v              A_Key  |
       Idel ----> KDowm ----> KUp
                  ^   |
                  |___|
                  A_Key

--------------------------------------
看得懂就看吧,看不懂就算了。。。。

#7


使用状态机。
以下以一个按键A为例:键值为A_Key(每一次收到A_Key表示按键A被按下一次).
假设每50ms扫描一次。

状态           意义
-------------------------------------
Idel  ---- 按键没有按下(初始状态)
KDowm ---- 按键按下
KUp   ---- 按键弹起
-------------------------------------
#########______________________
#########|                     |
#########|                     |
#########v              A_Key  |
########Idel ----> KDowm ----> KUp
###################^   |
###################|___|
###################A_Key

--------------------------------------
看得懂就看吧,看不懂就算了。。。。
格式问题。。。

#8


使用状态机。
以下以一个按键A为例:键值为A_Key(每一次收到A_Key表示按键A被按下一次).
假设每50ms扫描一次。

状态           意义
-------------------------------------
Idel  ---- 按键没有按下(初始状态)
KDowm ---- 按键按下
KUp   ---- 按键弹起
-------------------------------------
#########______________________
#########|#####################|
#########|#####################|
#########v##############A_Key##|
########Idel ----> KDowm ----> KUp
###################^###|
###################|###|
###################A_Key

--------------------------------------
看得懂就看吧,看不懂就算了。。。。
格式问题,把#号去掉看。。。

#9




使用状态机。
以下以一个按键A为例:键值为A_Key(每一次收到A_Key表示按键A被按下一次).
假设每50ms扫描一次。

状态           意义
-------------------------------------
Idel  ---- 按键没有按下(初始状态)
KDowm ---- 按键按下
KUp   ---- 按键弹起
-------------------------------------

         ______________________
         |                     |
         v              A_Key  |
        Idel ----> KDowm ----> KUp
                   ^   |
                   |___|
                   A_Key

--------------------------------------
看得懂就看吧,看不懂就算了。。。。
格式问题,把#号去掉看。。。

#10


终于对头了,瀑布汗

#11


判断按键抬起,从按下到抬起为一次按键,记录这个状态,计数器开始工作,到检测到下一次按键或者计数超时计数器可以停止计数,认为单次按键

长按就是检测到按键按下开始计数,到额定时间按键如果保持按下状态就认为长按
用状态机来做比较好

#12


前几天做了个抗抖  采样N次判断是否稳定
效果还不错,,就是浪费点资源  要一个定时器

#13


codehat 辛苦了

#14


顶11楼,那Codehat 说跟不说一个样,不看也罢