STM32 Cubemax(十一) ——利用状态机实现按键的长短按和双击
前言
状态机是一种根据当前状态来执行相应动作,根据输入去改变状态的方法,出处应该在数字电路中。 我们利用状态机的思想来实现按键的消抖和一些其他功能的实现
一、状态图
我们的按键实验,就是以此状态图为基础,然后做延申,实现长短按和双击。
二、Cubemax配置
1、IO口配置
这个配置很简单,看自己的板子上按键的IO口是哪个,我这里以KEY0做演示 配置PH3为输出IO,而且由电路图可知,应该设置为上拉。
2、定时器配置
我们需要配置一个10ms的定时器,以10ms去检测按键的状态
三、代码
1、编写有关按键的结构体和定义相关参数
#define IOSTATE HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_3)
typedef struct
{
uint8_t flag;
uint8_t mode;
uint8_t press_state;
}Key;
2、结构体初始化
void Key_Init()
{
key.mode = 2;
key.press_state = 0;
key.flag = 0;
HAL_TIM_Base_Start_IT(&htim2);
}
3、状态机编写
我这里用一个变量a去观察结果
void Key_Check()
{
static uint8_t state = 0, key_time = 0, twice_time = 0;
if(key.flag == 1)
{
twice_time++;
if(twice_time == 100)
{
twice_time = 0;
key.flag = 0;
}
}
switch(state)
{
case 0:
if(IOSTATE == key.press_state) state = 1;
break;
case 1:
if(IOSTATE == key.press_state)
{
if(key.mode == 0) a++;
else if(key.mode == 2)
{
key.flag++;
if(key.flag == 2)
{
a++;
key.flag = 0;
twice_time = 0;
}
}
state = 2;
}
else state = 0;
break;
case 2:
if(IOSTATE != key.press_state)
{
state = 0;
key_time = 0;
}
else if(key.mode == 1)
{
key_time++;
if(key_time == 50)
{
a++;
}
}
break;
}
}
4、10ms定时器中反复检测按键状态
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == htim2.Instance)
{
Key_Check();
}
}
总结
状态机的思想,适用于状态多变的场所,不仅是按键中。
|