当前位置: 首页 > news >正文

【STM32】状态机(State Machine)

这篇博客介绍 状态机(State Machine),适合用于嵌入式开发、驱动开发、协议解析、按键识别等多种场景。

一、什么是状态机(State Machine)?

状态机(State Machine)是一种用于描述系统行为的抽象模型,它能够根据当前状态和输入条件,转换到下一个状态,并执行相应操作。

在这里插入图片描述

使用场景常见有:

  • 按键消抖与识别
  • 通信协议(如 UART、Modbus、CAN)
  • 嵌入式流程控制(菜单系统、流程调度等)(我们此前的文章为贪吃蛇小游戏设计菜单系统 和 贪吃蛇的状态改变 便用到了状态机)
  • Linux 驱动状态切换
  • UI 界面状态设计
  • …等
二、状态机的基本组成
元素说明
状态(State)系统可能处于的状态集合,例如:IDLE、WAIT、RUN
事件/输入(Event)触发状态转移的条件,例如:按键按下、超时、数据接收
动作(Action)状态转移时执行的操作,例如:发送数据、点亮LED
转移(Transition)状态 + 输入 → 新状态 + 动作
状态机分类
类型说明示例
有限状态机(FSM)状态数量有限,事件驱动型按键识别
Mealy 状态机输出依赖于状态 + 输入通信协议
Moore 状态机输出只依赖当前状态电梯状态控制
层级状态机状态嵌套,适合复杂系统UI 菜单系统
三、状态机图示(例:按键识别)
+---------+      按下      +---------+
|  空闲态 | -------------> | 按下态  |
+---------+               +---------+^                         ||                         | 松开|                         v
+---------+ <------------- +---------+
| 单击处理 |               | 松开态  |
+---------+      超时      +---------+
四、代码模版说明(结构体 + 函数指针实现)

✅ 1. 状态定义

typedef enum {STATE_IDLE,STATE_PRESS,STATE_RELEASE,STATE_CLICK,STATE_MAX
} State_t;

✅ 2. 事件定义

typedef enum {EVENT_NONE,EVENT_KEY_DOWN,EVENT_KEY_UP,EVENT_TIMEOUT
} Event_t;

✅ 3. 状态处理函数指针表

typedef void (*ActionFunc)(void);typedef struct {State_t current_state;Event_t event;State_t next_state;ActionFunc action;
} StateTable_t;

✅ 4. 状态转移表

void do_nothing(void) {}
void handle_click(void) { printf("Click!\n"); }StateTable_t state_table[] = {{STATE_IDLE,    EVENT_KEY_DOWN,   STATE_PRESS,    do_nothing},{STATE_PRESS,   EVENT_KEY_UP,     STATE_CLICK,    handle_click},{STATE_CLICK,   EVENT_TIMEOUT,    STATE_IDLE,     do_nothing},{STATE_PRESS,   EVENT_TIMEOUT,    STATE_IDLE,     do_nothing},
};

✅ 5. 状态机执行函数

State_t current_state = STATE_IDLE;void state_machine_run(Event_t evt) {for (int i = 0; i < sizeof(state_table)/sizeof(StateTable_t); ++i) {if (state_table[i].current_state == current_state &&state_table[i].event == evt) {if (state_table[i].action) {state_table[i].action();}current_state = state_table[i].next_state;break;}}
}
状态机的实际作用:
场景						状态说明
按键处理					IDLE → PRESS → RELEASE → CLICK
通信协议					WAIT_RX → RECEIVING → PARSE → REPLY
UI 界面					主界面 → 设置界面 → 子菜单 → 返回
电机控制					停止 → 加速 → 稳速 → 减速

使用状态机时需要注意:① 状态机逻辑清晰,避免 if/else 嵌套过深;② 使用结构体+函数指针提高可扩展性;③ 可配合定时器、事件队列使用;④ 状态机应保持单一职责,避免过度复杂。

状态机调试方法:

状态打印					每次状态切换打印当前状态
图示辅助					画状态图帮助理清逻辑
加日志					用 log 函数记录状态流转
使用断点					在 state_machine_run() 中下断点观察转移

状态机是嵌入式开发中最实用的控制逻辑模型之一,掌握它能帮助在程序逻辑中有效管理复杂流程、提高代码可读性与可维护性。

以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!

http://www.dtcms.com/a/360759.html

相关文章:

  • 力扣每日一刷Day 19
  • RK3399内核驱动实战:获取设备号控制LED的四种方法(由浅入深、代码注释详尽)
  • 【CMake】Ctest,Cpack
  • 电子电气架构 --- 智能电动车EEA电子电气架构(上)
  • Linux | 走进网络世界:MAC、IP 与通信的那些事
  • 【macOS】垃圾箱中文件无法清理的--特殊方法
  • 深度学习跨领域应用探索:从技术落地到行业变革
  • 华为eNSP防火墙综合网络结构训练.docx
  • npm 打包上传命令,撤销错误版本
  • 山东省信息技术应用创新开展进程(一)
  • 设计模式13-迭代器模式
  • OS+MySQL+(其他)八股小记
  • 【lucene】 中的impactsenum与impactsdisi有啥区别?
  • 开源npm引导guide组件
  • 基于.NET Framework 4.0的FTP文件传输类
  • 基于Hadoop的可视化城市宜居指数分析(代码+数据库+LW)
  • 【macOS】垃圾箱中文件无法清理的常规方法
  • Mac上如何安装mysql
  • MIT 6.5840 (Spring, 2024) 通关指南——Lab 2: Key/Value Server
  • 【Docker】Docker容器和镜像管理常用命令
  • Spring Bean 生命周期中的 @PostConstruct 注解
  • TCP实现线程池竞争任务
  • LeetCode Hot 100 Python (31~40)
  • 运动规划实战案例 | 基于行人社交模型的移动机器人动态避障(附ROS C++仿真)
  • Linux Tun/Tap 多队列技术
  • 【STM32】贪吃蛇 [阶段2](嵌入式进阶方向)
  • 【含文档+PPT+源码】基于SpringBoot+微信小程序的饮水健康之净水器保养管理系统设计与实现【包运行成功】
  • 【Linux】模拟实现Shell(下)
  • 打开模板打印
  • Ajax笔记(下)