×
单片机 > 单片机程序设计 > 详情

基于状态机的51单片机独立按键检测与消抖思路

发布时间:2020-12-29 发布时间:
|

状态机的按键检测思路2
先回顾一下定义:
状态机有如下性质
按键状态机发生状态迁移的条件
如何准确检测条件是否发生并进行状态迁移
确保状态机能稳定地进行迁移
按键消抖的原理:状态切换
按键操作触发的时机

先回顾一下定义:
按键从未按下到按下,再到弹起,可以视为一个有4个状态的有限状态机。  分别是未按下、前沿抖动、按下、后沿抖动。  
即按键只在这4个状态间进行迁移,而且是当条件满足时按一定的顺序进行迁移:  未按下­­(条件1)­>前沿抖动­­(条件2)­>按下­­(条件3)­>后沿抖动­­(条件4)­>未按下  当且仅当条件成立时,才进行状态的迁移,当条件不成立时,状态机会保持当前状态不变。

状态机有如下性质

1.状态机会在条件满足时发生状态转移,由于每个状态会持续一段时间,而我们需要按键是理想的,即我们需要一个瞬间的按键事件,而不是连续的按键事件。  
总结:  
(1)当状态转移条件成立时,要进行状态的迁移。 
(2)状态转移是瞬间的,所以我们把某个状态转移当成按键来用。 
(3)未进行状态转移时,状态机会保持之前的状态。

按键状态机发生状态迁移的条件

 

即如何对状态机的迁移条件进行准确判定。  
如何准确检测条件是否发生并进行状态迁移
注意:按键的初始状态是未按下
//在定义时将按键状态初始化为未按下
unsigned char KEY_Status = NOPRESS;

(1)条件1:前沿抖动开始  
从未按下状态到前沿抖动开始这一事件发生,电平为由1变为0  
即在未按下状态下,突然检测到低电平,就说明迁移条件成立了,立即把状态迁移到前沿抖动,或执行其他操作。
//KEY_Status == NOPRESS && KEY_Value == 0,等价于条件1成立
if (NOPRESS ==  KEY_Status && 0 == KEY_Value)
{
KEY_Status = PRESHAKE; //执行状态迁移
timer(); //设置一个10ms定时器,用定时器溢出事件来模拟前沿抖动结束事件。
}

(2)条件2:前沿抖动结束  
从前沿抖动状态到前沿抖动结束这一事件发生,有大约10毫秒的时间,虽然没有具体的事件,但可以用定时器中断来模拟前沿抖动结束事件。在前沿抖动的状态下,一旦定时器中断,就说明迁移条件成立了,立即把状态迁移至按下,或执行其他操作。

  1. //若PRESHAKE == KEY_Status && 1 == TF1 则条件2成立

  2. if (PRESHAKE == KEY_Status && 1 == TF1)

  3. {

  4. KEY_Status = PRESS; //执行状态迁移

  5. TF = 0; //清除溢出标志

  6. TR1 = 0; //关闭定时器

  7. }


(3)条件3:后沿抖动开始  
从按下状态到后沿抖动开始这一事件发生,电平由0变1,即只要在按下状态中检测到电平为1,就认为迁移条件成立了,立即把状态迁移至后沿抖动。

  1. //KEY_Status == PRESS && KEY_Value == 1则条件3成立

  2. if (PRESS == KEY_Status && 1 == KEY_Value)

  3. {

  4. KEY_Status = TAILSHAKE; //执行状态迁移

  5. n++; //执行想要的操作

  6. timer(); //用定时器溢出来模拟后沿抖动结束事件

  7. }


(4)条件4:后沿抖动结束  
从后沿抖动状态到后沿抖动结束这一事件发生,虽然没有具体的事件,但是历时是确定的,基本在10ms左右,可以通过定时器溢出来模拟后沿抖动结束事件。一旦定时器溢出(或者定时器中断发生),就说明迁移条件成立了,立即把状态迁移至未按下。

//TF1 == 1即后沿抖动结束标志。
//要在此时关闭定时器,防止重复判断。
if (1 == TF1)
{
KEY_Status = NOPRESS;
TF1 = 0; //清除溢出标志
TR1 = 0; //关闭定时器
}

确保状态机能稳定地进行迁移

如果状态能稳定的迁移,也就是说如果我们能对状态发生迁移的条件进行准确判断,
状态机就会实现稳定的迁移。就可以在此基础上进行其他操作,不用担心状态机的状态界定错误,因为状态机是可以稳定迁移的。 

 
所以关键是对状态发生迁移的条件进行准确判定,从而使各个状态不发生交叉,即稳定迁移。  


要反复检查上面我们对状态机迁移条件界定是否准确。直到确定是准确的,就可以在此基础上做点别的事情了。  


可以在心中模拟程序执行来验证思路是否正确。

按键消抖的原理:状态切换

(按键)状态机中,由于状态的切换是通过判定条件来进行的,一旦条件成立,状态就瞬间切换了,每个状态会持续一段时间,在此期间循环可能会执行多次,但由于状态切换的条件不满足,所以不会进入if语句中操作。所以如果把任何状态切换到下一状态的瞬间当成按键事件,那么按键就只会被检测到一次,这就是按键消抖的原理。

按键操作触发的时机
实际测试发现,把对按键事件的响应操作放在后沿抖动开始时(即状态机由按下状态迁
移到后沿抖动状态的瞬间)效果比较不错,不会显得太敏感也不会显得很迟钝。


关键字:状态机  51单片机  独立按键检测  消抖 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR熔丝位操作时的要点和需要注意的相关事项