基于有限状态机的按键检测程序设计

2021-06-16 03:14龚利英
电子制作 2021年3期
关键词:端口按键编码

龚利英

(惠州经济职业技术学院,广东惠州,516057)

0 引言

键盘是单片机嵌入式系统中常见且非常重要的人机接口。从编码的功能上,键盘可以分成全编码键盘和非编码键盘两种。全编码键盘是由硬件完成键盘识别功能的,它通过识别键是否按下以及所按下键的位置,由全编码电路产生一个唯一对应的编码信息(如ASCII码)。非编码键盘是由软件完成键盘识别功能,它利用简单的硬件和一套专用键盘编码程序来识别按键的位置,然后由CPU将位置码通过查表程序转换成相应的编码信息。在单片机系统中,用的最多的是非编码键盘,其电路结构根据按键硬件连接方式可分为独立式按键、矩阵式按键和ADC按键等。在实际工程应用中,由于要考虑成本等因素,系统中的按键电路通常按键数目较少,需要软件程序的设计来实现嵌入式系统对按键复杂功能需求,使用软件来检测按键的一般思路是根据输入端口的状态及电平的持续时间,做出判断从而做出正确的动作。因此软件程序是非常的重要的,如果程序编写不合理就会出现按键失灵或误操作等情况。按键按下,按键抬起,按键持续按住一定时间等状态是一种有限状态的集合,本文针对单片机应用系统中按键结构形式的多样性,利用有限状态机设计一种高兼容性的按键检测系统,以此降低按键程序设计难度,减少工程人员在产品开发中的工作量。

1 有限状态机

图1 有限状态机的转换示意图

有限状态机是指在外界条件的作用下,在有限个状态之间进行状态转移的数学模型,如图1所示,其中Q表示有限状态,e表示触发条件。在实际应用中,根据逻辑功能,有限状态机有Moore型和Mealy型两种类型。Moore型有限状态机某时刻的输出,只取决于该时刻的输入,与前一个状态没有关系,可将该类型状态机看作组合逻辑电路;Mealy型有限状态机该时刻的输出不仅取决于该时刻的输入,还与前一个状态有关,该种状态机可视为时序逻辑电路。

2 按键状态分析

■2.1 按键的检测事件

CPU通过检测按键的状态接收用户发出的指令,并做出相应的动作。这个过程通常由软件实现,一般情况下按键检测事件可分为:按键按下、按键按下后松开、按键短按住、按键短按住后松开、按键短按住后重复、按键长按住、按键长按住后松开、按键长按住后重复,其中事件触发时间可自行定义。

■2.2 按键时间与状态转换分析

在单片机应用系统中,一般按键数目较少,可以通过对按键时间的长短对事件进行划分,即在指定时间范围为一个事件。因此程序设计的关键是实现按键时间与事件状态的转换,转换关系如图2所示。

按键检测程序每个系统节拍执行一次。按键检测步骤如下:

(1) 在没有检测到按键按下时,设定按键状态为NONE和前次按键值为NOKEY;

(2) 在检测到有按键按下并且按下的按键与前一次检测到的按键值不一样时,更新前次按键值为新的键值,初始化两个按键计数器keyCntr和keyCntrLong的值为0;

(3) 在检测到有按键按下并且按下的按键与前一次检测到的按键值一样时,两个按键计数器keyCntr和keyCntrLong的值自增1:

若当前按键状态是NONE,在keyCntr计数值超过按键消抖时间 KEY_TIME_PRESS后,触发按键按下PRESS事件,按键状态更新为PRESS;

若当前按键状态是PRESS,在keyCntr计数值超过按键短按住时间;KEY_TIME_SHORT_HOLD后,触发按键短按住SHORT_HOLD事件,按键状态更新为SHORT_HOLD,同时keyCntr减去一个按键短按住后重复时间KEY_TIME_SHORT_HOLD_REPEAT;

图2 按键状态分析

若当前按键状态是SHORT_HOLD_REPEAT,在keyCntr计数值超过按键短按住时间KEY_TIME_SHORT_HOLD后,再次触发SHORT_HOLD_REPEAT事件,同时keyCntr减去一个按键短按住后重复时间KEY_TIME_SHORT_HOLD_REPEAT;此时如果keyCntrLong计数值也超过按键长按住时间KEY_TIME_LONG_HOLD,则触发LONG_HOLD事件,按键状态更新为LONG_HOLD,同时keyCntrLong减去一个按键长按住后重复时间KEY_TIME_LONG_HOLD_REPEAT;

若当前按键状态是LONG_HOLD,在keyCntrLong计数值超过按键长按住时间KEY_TIME_LONG_HOLD后,触发LONG_HOLD_REPEAT事件,按键状态更新为LONG_HOLD_REPEAT,同时keyCntrLong减去一个按键长按住后重复时间KEY_TIME_LONG_HOLD_REPEAT;

若当前按键状态是LONG_HOLD_REPEAT,在keyCntrLong计数值超过按键长按住时间KEY_TIME_LONG_HOLD后,再次触发LONG_HOLD_REPEAT事件,同时keyCntrLong减去一个按键长按住后重复时间KEY_TIME_LONG_HOLD_REPEAT;

(4)在检测到按键松开时:

若当前按键状态是PRESS,触发PRESS_RELEASE事件;

若当前按键状态是SHORT_HOLD或SHORT_HOLD_REPEAT,触发SHORT_HOLD_RELEASE事件;

若当前按键状态是LONG_HOLD或LONG_HOLD_REPEAT,触发LONG_HOLD_RELEASE事件;

并且将按键状态更新为NONE,前次按键值为NOKEY。

3 按键的程序设计

■3.1 基于有限状态机按键检测程序流程

程序设计的关键点是识别当前的状态及触发的外部条件,进行下一状态的转换,程序流程如图3所示。该程序思路适合独立式按键、矩阵式按键和ADC按键等多种结构形式的按键电路,在检测端口状态时,若是独立式按键就直接读取端口;若是矩阵式按键则需要设置相应端口输出输入状态后再读取端口,注意防止损坏端口的可能性;若是ADC按键则要切换相应ADC通道后再读取端口,同时要保证通道切换的正确性,且需要多次读取平均值,如果是组合按键的成员必须在不同的ADC端口上。

图3 按键检测流程

■3.2 按键事件的散转处理

按键状态的识别及状态的转换,最终目的是让对应的事件得到响应,程序设计上通过将按键值、按键状态和按键事件一一进行匹配,使用一个二维数组将三者一一对应起来。按键值索引keyIndex,按键状态索引keyStateIndex,按键事件表KeyEventTable。

KeyEventTable [keyIndex][ keyStateIndex]=

{

// keyIndex=0

{KEY0_NONE, KEY0_PRESS, KEY0_PRESS_RELEASE, KEY0_SHORT_HOLD, KEY0_SHORT_HOLD_RELEASE, KEY0_SHORT_HOLD_REPEAT, KEY0_LONG_HOLD, KEY0_LONG_HOLD_RELEASE, KEY0_LONG_HOLD_REPEAT},

// keyIndex=1

{KEY1_NONE, KEY1_PRESS, KEY1_PRESS_RELEASE, KEY1_SHORT_HOLD, KEY1_SHORT_HOLD_RELEASE, KEY1_SHORT_HOLD_REPEAT, KEY1_LONG_HOLD, KEY1_LONG_HOLD_RELEASE, KEY1_LONG_HOLD_REPEAT},

……

};

4 小结

本文设计了一种高兼容性的按键检测程序。程序的思路是预先将所有按键可能产生的按键动作编上编号,并用二维数组将编号和对应的执行函数联系到一起,然后在程序运行时,根据当前检测到的按键值和按键状态值,查找到对应的按键事件执行函数并执行之。

此程序设计具有较高的兼容性和实用性,可应用于单片机嵌入式系统中的独立式按键、键盘按键、ADC按键。在使用此程序进行单片机系统设计中应注意如下几个问题:

(1)需要占用一部分ROM空间来存放按键事件表;

(2)各个按键值、按键状态和按键事件表的排序需要一一对应,如果对应出错,则相应的按键功能必然出错;

(3)按键事件没有超出255个时,按键事件表的大小就等于按键事件数目,字节如果超出了255个,则按键事件表的大小将需要占用按键事件数*2字节的ROM空间,实际应用中应该对按键事件数目加以限制。

猜你喜欢
端口按键编码
HEVC对偶编码单元划分优化算法
温度对圆柱壳结构应力及端口变形影响研究
华为交换机端口Hybrid 模式的应用
住院病案首页ICD编码质量在DRG付费中的应用
一种端口故障的解决方案
非触勿动 秒治键盘误触
未来的笔
为程序或设备在路由器上打开端口
其实真的很简单教你轻松关闭WP8.1手机按键灯
计算器