当前位置:首页 > 技术心得 > 正文内容

基于状态机实现的按键处理算法

xjtudll13年前 (2012-11-18)技术心得18006

这篇文章写了很久了,一直没发,现在发出来吧。

关于按键的基础知识,这里就不多写了,可以参考程序匠人的《按键漫谈》

一次完整的击键过程包括:等待阶段,闭合抖动阶段,有效闭合阶段,释放抖动阶段,有效释放阶段。释放抖动阶段对于按键处理用处不大,所以这个阶段被忽略了,即按键击键包括四个状态:等待阶段,闭合抖动阶段,有效闭合阶段,释放抖动阶段。

设等待阶段为A状态,闭合抖动阶段为B状态,有效闭合阶段为C状态,释放抖动阶段为D状态。各状态之间的转换关系如图:

未命名

A:等待阶段。此阶段若碰到有按键,立即转向B阶段。此阶段处理无击。

B:闭合抖动阶段。此阶段若本次键值=备份键值,则转向C阶段。否则,备份键值=本次键值,继续下一次判断。

C:有效闭合阶段。此阶段若检测到无效按键,则转向D阶段。此阶段处理长击和连击。

D:按键释放阶段。此阶段执行完按键散转程序后,可直接跳到A阶段。此阶段处理单击。

检测到按键后,10ms扫描一次按键,获取键值。当然也可以不管有没有按键,都10ms扫描一次。

按键处理程序需要变量

变量名

作用

key_state

按键当前状态 0-等待阶段;1-闭合抖动阶段;2-有效闭合阶段 3-释放阶段

key_type

击键类型 0-无按键或按键已响应;1-单击;2-连击;3-长击;4-无击

key_detect

按键检测标志 0-无按键;1-检测到按键按下

key_disbale

按键是否已经响应 1表示已经响应。用于长击。

key_scan_en

按键允许扫描标志 0-不允许扫描;1-允许扫描(一般10ms允许一次扫描)

key_value

当前键值

key_backvalue

备份键值

key_tmr_no

无键计数器,用于无击

key_cnt_press

按键闭合计数器,用于长击

key_delay_con

连击响应延时时间,即多长时间响应一次连击

按键处理程序需要常量:

常量

作用

AN_XD_DL

连击 初键延时时间(AN_XD_DL*定时扫描时间)

AN_LA_DL

连击响应时间(AN_LA_DL*定时扫描时间)

AN_CJ_DL

长击所需时间(AN_CJ_DL* AN_LA_DL*定时扫描时间)

NoKeyTMR

无键响应时间

各阶段程序流程图:

A:等待阶段

clip_image005[4]

B:按键抖动阶段

此阶段较为简单。在按键允许扫描标志置1后,开始扫描,获取键值。若当前键值key_value=备份键值key_backvalue,转向闭合阶段,否则 备份键值=当前键值。另外此阶段要对无键计数器清零。

C:按键有效闭合阶段

需要注意的是,在按键散转后,需要对某些变量清零。

流程图如下:

clip_image007[4]

D:释放阶段

本阶段处理的是单击程序。此处需要避免长击和单击冲突。执行完后,立即转向等待阶段。

根据键值散转处理时,请注意:一个按键可以:只支持单击,只支持长击,只支持连击,支持单击和长击。连击实际上包含了单击(根据初键延时时间AN_XD_DL来确定按键的灵敏度)。散转时不要对同一个按键执行冲突的操作(比如连击和长击)。

扫描二维码推送至手机访问。

版权声明:本文由鸟的天空发布,如需转载请注明出处。

本文链接:http://xjtudll.cn/Exp/250/

标签: 键盘单片机
分享给朋友:

“基于状态机实现的按键处理算法” 的相关文章

Windows7画图调整橡皮擦大小

Windows7画图调整橡皮擦大小

Windows7自带的画图软件,如何调整橡皮擦大小呢? 方法1:选中橡皮擦 ,在菜单栏找到“粗细”,选中不同的宽度即可。如下图所示。但是这个方法有个缺点,如果要将橡皮擦调整到很小的宽度,则没法实现。 例如,想使用1px的橡皮擦,怎么办? 这个时候就要用到方法2了。 方法2:...

TM87&TM89烧录

TM87&TM89烧录

一、如何查询TM87&TM89烧录引脚通过TWR98烧录软件,我们可以查询到相关IC的烧录引脚以及与烧录器的连接方式。TWR98的详细使用方法,可以参考《UM-TWR98_SV12.pdf》1、打开TWR98烧录软件2、点【Device】,选IC型号若要支持更多的IC型号,应确保TWR98烧...

LCD基本常识

1、LCD的玻璃厚度有1.1mm、0.7mm、0.55mm和0.4mm,成品总厚度分别为2.8mm、2.0mm、1.7mm和1.4mm,如果是FSTN产品,那么总厚度需要再增加0.1mm。 2、LCD的视角范围,STN产品视角范围最大,HTN产品次之,TN产品视角范围最小。对于多路产品,如果路数大于...

C# MDI 子窗体被父窗体控件挡住

C# MDI 子窗体被父窗体控件挡住

https://blog.csdn.net/chenyblog/article/details/40752029最近在做一个小工具,发现了一个过去做项目没有遇到的问题:子窗体被父窗体的控件给挡住了!如下图所示:子窗体的TopMost 已经设为true,父窗体的控件已经置于底层,但是结果还是很悲观!无...

如何通过程序清除蓝牙缓存的设备名称?

http://stackoverflow.com/questions/10793761/how-to-programmatically-clear-the-bluetooth-name-cache-in-android 现象: 一个已经配对过的蓝牙设备,修改名称之后,手机上显示的依旧是以前的名称,并...

Keil单工程多Target的配置方法

Keil单工程多Target的配置方法

实现功能: 通过切换target实现不同的编译设置,而无需建立多个工程 需求背景: 调试一些算法,想使用STM32F107VCT6,但是发现STM32F107不能仿真,只有STM32F103可以仿真。 由于没有STM32F107VCT6实物,所以初期只能使用STM32F103仿真了。 STM32F1...

评论列表

winxos
winxos IP:四川省
13年前 (2013-03-11)

楼主功力深厚啊。

rqhdckyam
rqhdckyam IP:
13年前 (2012-12-18)

IGMOCO <a href="http://yhbxhynnskxt.com/">yhbxhynnskxt</a>

hqlpoui
hqlpoui IP:
13年前 (2012-12-16)

1370iQ , [url=http://dpcquzabytoz.com/]dpcquzabytoz[/url], [link=http://ywzgaqjfclfl.com/]ywzgaqjfclfl[/link], http://ewsshgvybtdq.com/

mjevwc
mjevwc IP:
13年前 (2012-12-16)

UNIEAv <a href="http://xfpeypkfdgum.com/">xfpeypkfdgum</a>

Atarah
Atarah IP:江苏省
13年前 (2012-12-15)

You're the one with the brains here. I'm watcihng for your posts.

sea
sea IP:广东省
13年前 (2012-11-20)

就差点程序 就很好了

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。