状态机的设计流程

SM的设计
以红绿灯🚥系统为例,进行状态机设计流程的讲解

第一步:明确系统功能需求(What?)

  • 有哪些状态 有三种状态:红灯、黄灯、绿灯
  • 状态之间怎么切换
    • 状态按顺序循环:绿灯5 秒 → 黄灯2 秒 → 红灯5 秒 → 绿灯
  • 是否有外部事件影响? 没有外部事件

结论:这是一个定时驱动的循环状态机

第二步:有哪些状态? 列出所有状态(States)及含义

  • GREEN、YELLOW和RED

第三步:状态怎么跳? 定义状态转移逻辑(Transitions)

确定转移条件:这里是“时间”

  • GREEN → YELLOW:绿灯持续5秒后
  • YELLOW → RED:黄灯持续2秒后
  • RED → GREEN:红灯持续5秒后

第四步:每个状态做什么? 确定每个状态的行为(Actions)

每个状态通常有两个行为:进入和运行

交通灯状态动作表

状态 Enter 动作 Run 动作
GREEN 打印"绿灯亮起" 倒计时,计满5秒后状态切换
YELLOW 打印"黄灯亮起" 倒计时,计满2秒后状态切换
RED 打印"红灯亮起" 倒计时,计满5秒后状态切换

第五步:选择状态机实现模式

模式 适用场景
switch-case 状态少、逻辑简单
函数指针表(表格驱动) 状态较多、结构清晰、易扩展

模式结构设计

typedef struct {
    void (*Enter)(void);  // 进入函数
    void (*Run)(void);    // 运行函数
} StateHandler_t;

定义状态表

const StateHandler_t StateTable[] = {
    [STATE_GREEN]  = { .Enter = Green_Enter,  .Run = Green_Run },
    [STATE_YELLOW] = { .Enter = Yellow_Enter, .Run = Yellow_Run },
    [STATE_RED]    = { .Enter = Red_Enter,    .Run = Red_Run }
};

第六步:设计状态变量和驱动机制

  • 当前状态变量
State_t currentState = STATE_RED;  // 初始状态
  • 驱动机制(主循环)
while (1) {
    StateTable[currentState].Run();   // 执行当前状态的运行逻辑
    delay(1000);                      // 模拟1秒间隔
}
posted @ 2025-08-12 15:01  lei_2024  阅读(58)  评论(0)    收藏  举报