前言
状态机是一种根据当前状态来执行相应动作,根据输入去改变状态的方法,出处应该在数字电路中。
我们利用状态机的思想来实现按键的消抖和一些其他功能的实现
一、状态图
我们的按键实验,就是以此状态图为基础,然后做延申,实现长短按和双击。
二、Cubemax配置
1、IO口配置
这个配置很简单,看自己的板子上按键的IO口是哪个,我这里以KEY0做演示
配置PH3为输出IO,而且由电路图可知,应该设置为上拉。
2、定时器配置
我们需要配置一个10ms的定时器,以10ms去检测按键的状态
三、代码
1、编写有关按键的结构体和定义相关参数
#define IOSTATE HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_3) //读取PH3的IO信息
typedef struct
{
uint8_t flag; //双击标志
uint8_t mode; //按键模式,0为短按,1为长按,2为双击
uint8_t press_state; //表示按键按下时,IO口为高电平还是低电平
}Key;
2、结构体初始化
void Key_Init()
{
key.mode = 2;
key.press_state = 0;
key.flag = 0;
HAL_TIM_Base_Start_IT(&htim2);
}
3、状态机编写
我这里用一个变量a去观察结果
//此函数在定时器中每10ms调用一次
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();
}
}
总结
状态机的思想,适用于状态多变的场所,不仅是按键中。
上一篇:STM32 Cubemax(十三) ——SPI时序读写RFID-RC522
下一篇:STM32 Cubemax(十一) ——JY901陀螺仪数据的读取与简单数据处理
推荐阅读最新更新时间:2024-11-12 10:55
设计资源 培训 开发板 精华推荐
- 用于工业的 2-LED 大功率 LED 驱动器
- LTC7130EY 具有极低输出纹波的高效、1.5V/15A 降压转换器的典型应用电路
- LTC3126MPFE 5V、2A 电源的典型应用电路,由墙上适配器和铅酸备用电池供电
- 使用 Analog Devices 的 LTC1261CS 的参考设计
- IP6505 双路桌充
- S32R372EVB: 恩智浦S32R372雷达处理MCU 141BGA评估板
- OP482ACBZ-R7 低功耗、高速 JFET 运算放大器的典型应用电路
- MC32PF3000A7EP PMIC 解决方案电源管理的典型应用
- 使用具有最大功率点跟踪功能的 LTC4162IUFD-LAD 太阳能供电 36 节 3.2A 充电器的典型应用
- 使用 Analog Devices 的 LTM4602EV 的参考设计