专项:STM32状态机结构简述
前言
在 STM32 开发中,状态机是一种常用的编程结构,用于处理复杂的逻辑流程和事件驱动的系统。状态机通过定义不同的状态以及状态之间的转换条件,使得程序逻辑更加清晰、易于维护和扩展。如果没有自己的编程习惯,可以使用状态机结构编程。
基本结构
1. 状态(State)
状态是状态机在某一时刻所处的情况。例如,在 LED 亮灭控制状态机中,有led亮和led灭两个状态[struct{on,off};],每个状态都有其特定的行为控制和可能的转换方式。
2. 事件(Event)
事件是触发状态转换的条件(类似于QT信号传递)。它可以是外部输入(如按键按下、传感器信号变化)、定时器超时等。例如,在 LED 控制状态机中,“按下按键” 这个事件可以触发从 “LED 熄灭” 状态转换到 “LED 点亮” 状态[if(key==1){state=on}else{state=off}]。
3. 转换(Transition)
转换定义了状态之间的迁移规则,即当某个事件发生时,状态机从一个状态转换到另一个状态[state=on/state=off]。每个转换都与一个特定的事件相关联。
4. 动作(Action)
动作是状态机在进入某个状态、离开某个状态或在状态转换过程中执行的操作(执行事件)。例如,在进入 “LED 点亮” 状态时,执行点亮 LED 的操作。
实现方式
1. 枚举定义状态
使用枚举类型来定义状态机的所有可能状态[不可使用{1,2,3,4}这种定义,维护比较困难]。
typedef enum {
STATE_IDLE, // 空闲
STATE_RUNNING, // 运行
STATE_ERROR // 错误
} State_t;
2. 状态处理函数
为每个状态编写对应的处理函数(事件),这些函数负责处理该状态下的具体操作和状态转换逻辑。
//空闲
void StateIdleHandler(void) {
if (events1()) {
//其他需要执行的事件
currentState = STATE_RUNNING; // 转换到运行状态
}
}
//运行
void StateRunningHandler(void) {
if (events2()) {
//运行事件
currentState = STATE_ERROR; // 如果错误转换到错误状态,没有的话进进入正常状态机
}
}
//错误
void StateErrorHandler(void) {
TurnOnErrorLED();
// 错误处理
if (errorevents()) {//处理完成,进入空闲
currentState = STATE_IDLE; // 转换到空闲状态
}
}
3. 主循环中的状态机调度
在main中,根据当前状态调用相应的状态处理函数。
State_t currentState = STATE_IDLE;//在系统启动时,自动进入一个待机状态
int main(void) {
while (1) {
switch (currentState) {//状态机切换状态。
case STATE_IDLE:
StateIdleHandler();
break;
case STATE_RUNNING:
StateRunningHandler();
break;
case STATE_ERROR:
StateErrorHandler();
break;
default:
// 处理未知状态,最后回到状态中,不能死循环
break;
}
}
}
总结
通过状态机结构,可以将复杂的系统逻辑分解为多个简单的状态和状态转换,使得代码的可读性和可维护性大大提高。在 STM32 开发中,状态机常用于处理按键输入、传感器数据处理、通信协议解析等场景,使用和学习中尽量多使用状态机模式。