嵌入式状态机设计——两个变量就够了

发布时间:2026/7/21 10:03:36
嵌入式状态机设计——两个变量就够了 一句话: 设备启动需要多步序列加热A→加热B→开输出同时要随时关机、空闲手动控制。用两个变量触发标志 状态位就能全覆盖比五六个标志位乱飞强得多。适合谁读写嵌入式控制逻辑状态变量越加越多的开发者。需求一个多步骤启动流程步骤1 就绪 → 步骤2 就绪 → 步骤3 开输出需求说明随时关断任意时刻收到关断指令 → 立刻全关 → 回到初始态关断后不重复全关后不会自动重开空闲时手动控制平时可以自由操作各模块自动/手动不冲突序列跑着时手动操作不干扰加一堆独立变量——启动标志、关断标志、忙标志、自动模式标志——很快互相矛盾。两个变量typedef enum { SEQ_IDLE 0, SEQ_STEP1_START, SEQ_STEP2_START, SEQ_OUTPUT_ON } E_SEQ_STATE; volatile uint8_t g_bTrig; // 触发标志1请求启动0请求关断 volatile E_SEQ_STATE g_eSeqState; // 当前序列状态状态机void Sequence_Run(void) { /* 关断路径 —— 优先级最高 */ if (g_bTrig 0) { if (g_eSeqState ! SEQ_IDLE) { Module_Off(2); // 先关输出 Module_Off(0); // 再关加热A Module_Off(1); // 再关加热B g_eSeqState SEQ_IDLE; } return; } /* 启动路径 */ switch (g_eSeqState) { case SEQ_IDLE: Module_Start(0, SETPOINT_A); g_eSeqState SEQ_STEP1_START; break; case SEQ_STEP1_START: if (Module_Ready(0)) { Module_Start(1, SETPOINT_B); g_eSeqState SEQ_STEP2_START; } break; case SEQ_STEP2_START: if (Module_Ready(1)) { Output_On(); g_eSeqState SEQ_OUTPUT_ON; } break; case SEQ_OUTPUT_ON: break; // 保持等关断 } }四种行为全覆盖g_bTrigg_eSeqState行为0IDLE空闲手动控制有效0≠ IDLE关断路径全关 → IDLE1IDLE启动序列开步骤11≠ IDLE继续跑当前序列IDLE 状态天然实现了空闲时手动控制——不需要额外标志。为什么比多标志好方案变量数状态空间多标志启动/关断/忙/自动/手动532 种组合只有 4 种合法两变量标志状态24 种全部合法多标志方案藏着大量非法组合。两变量方案跑不出非法状态。实测对比多标志方案: 5变量32种组合藏大量非法状态 | 两变量: 4种合法状态全覆盖有用的话点个收藏下次调试直接用。有问题欢迎评论区交流看到了都会回。下一篇dead-code-chain-deletion——状态机、编码规范、编译链接——每个嵌入式新人都要过的三道坎