前言
在 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 开发中,状态机常用于处理按键输入、传感器数据处理、通信协议解析等场景,使用和学习中尽量多使用状态机模式。