4. 洗衣机控制程序状态机设计
任务目标
为洗衣机控制器设计一个有限状态机(FSM),覆盖待机、注水、洗涤、漂洗、脱水、结束六个主状态,并处理门锁互锁与故障中断逻辑。程序需在检测到故障时进入故障状态,故障恢复后返回待机;门锁仅在非运行状态下允许打开。
状态定义与迁移条件
| 当前状态 | 触发事件 | 动作 | 下一状态 |
|---|---|---|---|
| IDLE(待机) | start_pressed && door_locked | 启动注水 | FILL |
| FILL(注水) | water_full | 停止注水,开始洗涤 | WASH |
| WASH(洗涤) | wash_done | 排水并进入漂洗 | RINSE |
| RINSE(漂洗) | rinse_done | 排水并开始脱水 | SPIN |
| SPIN(脱水) | spin_done | 停止电机,解锁门锁 | END |
| END(结束) | door_opened | 回到待机 | IDLE |
| 任意非IDLE状态 | fault_detected | 停止所有执行器,锁定门 | FAULT |
| FAULT(故障) | fault_cleared | 复位执行器,解锁门 | IDLE |
关键完整代码(C语言实现)
#include <stdbool.h>
typedef enum {
IDLE, FILL, WASH, RINSE, SPIN, END, FAULT
} State;
typedef struct {
bool start_pressed;
bool door_locked;
bool water_full;
bool wash_done;
bool rinse_done;
bool spin_done;
bool door_opened;
bool fault_detected;
bool fault_cleared;
} Event;
typedef struct {
State current;
bool door_lock_output;
bool water_valve;
bool motor;
bool drain_pump;
} WasherFSM;
void fsm_init(WasherFSM *m) {
m->current = IDLE;
m->door_lock_output = false;
m->water_valve = false;
m->motor = false;
m->drain_pump = false;
}
void fsm_run(WasherFSM *m, Event *e) {
// 故障优先级最高:任何非IDLE状态检测到故障立即进入FAULT
if (e->fault_detected && m->current != IDLE && m->current != FAULT) {
m->current = FAULT;
m->door_lock_output = true; // 故障时锁门
m->water_valve = false;
m->motor = false;
m->drain_pump = false;
return;
}
switch (m->current) {
case IDLE:
if (e->start_pressed && e->door_locked) {
m->current = FILL;
m->water_valve = true;
m->door_lock_output = true;
}
break;
case FILL:
if (e->water_full) {
m->current = WASH;
m->water_valve = false;
m->motor = true;
}
break;
case WASH:
if (e->wash_done) {
m->current = RINSE;
m->motor = false;
m->drain_pump = true;
}
break;
case RINSE:
if (e->rinse_done) {
m->current = SPIN;
m->drain_pump = false;
m->motor = true;
}
break;
case SPIN:
if (e->spin_done) {
m->current = END;
m->motor = false;
m->door_lock_output = false; // 脱水完成解锁
}
break;
case END:
if (e->door_opened) {
m->current = IDLE;
}
break;
case FAULT:
if (e->fault_cleared) {
m->current = IDLE;
m->door_lock_output = false;
}
break;
}
}
运行与验证
编译:将上述代码保存为 washer_fsm.c,使用 gcc -Wall -o washer_fsm washer_fsm.c 编译(需自行添加包含 main() 的测试文件)。
最小验证步骤:
- 初始化
WasherFSM m; fsm_init(&m);,断言m.current == IDLE。 - 设置
e = {.start_pressed=true, .door_locked=true},调用fsm_run(&m, &e),断言m.current == FILL且m.water_valve == true。 - 依次触发
water_full、wash_done、rinse_done、spin_done,每步调用后断言状态分别变为 WASH、RINSE、SPIN、END。 - 在 WASH 状态设置
fault_detected=true,调用后断言m.current == FAULT且m.motor == false、m.door_lock_output == true。 - 设置
fault_cleared=true,调用后断言回到 IDLE 且门锁解锁。
通过条件:以上断言全部成立,且门锁在 FILL~SPIN 期间始终为 true,在 END 状态变为 false,故障时强制锁定。
状态迁移图
说明:图中实线为正常流程,红色虚线为故障中断(从任意运行状态进入 FAULT),绿色虚线为故障恢复路径。门锁输出在 FILL 至 SPIN 期间保持锁定,END 状态解锁,FAULT 状态强制锁定。