基于状态机的单片机按键短按长按功能的实现

控制/MCU

1878人已加入

描述

1、引言

在自己在科研实践和对学生教学中发现,现在单片机学习中对于按键处理的方法都是:检测按键、延时消抖、按键执行、等待释放,整个按键处理的程序中大量出现“delay_1ms(5);”和“while(!key);”这样的语句,这明显是在给自己找麻烦,延时消抖与等待释放需要消耗CPU运行时间,执行效率低下,而且这种方法处理的按键程序也实现不了按键的短按、长按等灵活的按键操作方式。本文讲述了一种用状态机实现按键扫描的方法,达到按键的短按和长按功能,高效的处理按键消抖问题。

2、状态机

状态机在软件编程中非常重要,一个思路清晰而且高效的程序,必然有状态机的身影浮现。比如在按键命令解析程序中,本来是在状态1中,触发一个按键后切换到状态2,再触发另一个按键切换到状态3,或者返回到状态1。按键的击键过程也是一种状态的切换,也可以看着是一个状态机,一个按键的击键过程包括:按下、抖动、闭合、抖动和释放等状态。我们只要把这些状态机的思想想办法用程序表示出来就可以了。

3、按键的状态机实现

我们这里用状态机是为解决问题的,那么我们就要从问题本身去思考。为了实现按键扫描,达到按键短按和长按的功能,可以根据一个按键从按下按键到释放按键的整个过程将按键分为4个状态:

S0:等待按键按下

S1:按键按下

S2:等待按键短按释放

S3:等待按键长按释放

假设按键按下为低电平“0”,按键未按下为高电平“1”,按键的整个过程我们就可以通过状态转移图表示出来,如图1所示。

状态机

图1:按键的状态转移图

首先,按键的初始状态为S0,当检测到输入为1时,表示按键没有按下,保持S0;当输入为0时,表示按键按下,状态转入S1。在S1状态中,检测输入信号是否为0,如果为0,执行按键程序转入S2;如果为1,表示之前的按键操作是干扰信号,回到S0。在S2状态中,如果输入信号是1,则回到S0,表示按键短按已经释放;如果按键没有释放,输入为0时,就开始计时,计时没有结束前一直在S2,当计时结束了,转入S3,表示按键一直按着,为长按功能,在S2计时过程中,输入从0变为1也会回到S0。在S3状态中,输入信号为1,返回S0,表示按键长按释放;输入信号为0,执行相应的按键程序,也可以计时,等计时结束执行按键程序,达到按键连击的功能。这就是采用状态机进行按键检测达到短按与长按的整个过程。

下面以四个按键接在P1的P1.7、P1.6、P1.5、P1.4,设计状态机按键扫描程序。

程序代码如下:

#defineS00//状态0

#defineS11//状态1

#defineS22//状态2

#defineS33//状态3

voidkey()

{staticunsignedcharstate=S0,key_time;

unsignedcharkey;

key=P1&0xf0;//屏蔽P1低四位

switch(state)//检测状态

{caseS0://状态0

if(key!=0xf0)state=S1;break;//判断输入是否为0,为0转入状态1

caseS1://状态1

if(key==0xf0)state=S0;//判断输入是否为1,为1返回状态0

else//否则,转入状态2,执行按键程序

{state=S2;

switch(key)

{case0xe0:/*按键1执行程序*/

break;

case0xd0:/*按键2执行程序*/break;

case0xb0:/*按键3执行程序*/break;

case0x70:/*按键4执行程序*/break;}}

break;

caseS2://状态2

if(key==0xf0)state=S0;//判断输入是否为1,为1返回状态0

elseif(++key_time==100){key_

time=0;state=S3;}break;

//否则开始计时,计时结束转入状态3

caseS3://状态3

if(key==0xf0)state=S0;//判断输入是否为1,为1返回状态0

elseif(++key_time==5)//否则开始计时,计时结束按键连击

{key_time=0;

switch(key){

case0xe0:break;

case0xd0:break;

case0xb0:break;

case0x70:break;}

}break;}}

4、中断处理按键消抖

通常使用的按键都是机械弹性按键,也就是轻触开关。机械按键在触点的闭合和断开的过程中会产生抖动,一个按键在按下时不会立刻稳定的导通,在释放时也一样,不会一下子就断开,在按下和释放瞬间都会有一连串的抖动现象。按键的抖动时间有按键的机械特性决定,一般情况为5ms~10ms。这种抖动人是感觉不出来的,但是单片机的运行速度是微秒级的,这里可以设计一个定时中断来检测按键的状态,通过定时中断来消除按键抖动问题。因此可以把定时器的时间设置为10ms,每隔10ms进入一次中断检测一次按键的状态。

5、总结

本文介绍的这种以状态机来实现按键检测的方法,与一般的按键检测方法相对比,能完成案件的多种状态的检测,实现按键的短按和长按功能。采用状态机编写的按键程序也大大的改进了按键消抖对CPU运行时间消耗的问题。程序代码简单,维护方便,适用范围广。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分