4. 洗衣机控制状态机
任务说明
设计并实现一个洗衣机控制状态机,覆盖注水→洗涤→漂洗→脱水→结束的主流程,同时支持运行中的暂停/继续与取消操作。状态机采用经典FSM结构,通过事件驱动完成状态迁移,可直接编译运行并观察状态变化日志。
状态定义与迁移规则
| 当前状态 | 触发事件 | 动作 | 下一状态 |
|---|---|---|---|
| IDLE | START | 开始注水 | FILLING |
| FILLING | WATER_FULL | 启动电机洗涤 | WASHING |
| WASHING | WASH_DONE | 排水并注水 | RINSING |
| RINSING | RINSE_DONE | 启动脱水 | SPINNING |
| SPINNING | SPIN_DONE | 停机 | FINISHED |
| 任意非终态 | PAUSE | 暂停当前动作 | PAUSED |
| PAUSED | RESUME | 恢复暂停前状态 | 暂停前状态 |
| 任意非终态 | CANCEL | 停止并排水 | IDLE |
完整实现代码
#include <stdio.h>
#include <string.h>
typedef enum {
IDLE, FILLING, WASHING, RINSING, SPINNING, PAUSED, FINISHED
} State;
typedef enum {
START, WATER_FULL, WASH_DONE, RINSE_DONE, SPIN_DONE,
PAUSE, RESUME, CANCEL
} Event;
const char* state_name(State s) {
switch(s) {
case IDLE: return "IDLE";
case FILLING: return "FILLING";
case WASHING: return "WASHING";
case RINSING: return "RINSING";
case SPINNING: return "SPINNING";
case PAUSED: return "PAUSED";
case FINISHED: return "FINISHED";
}
return "UNKNOWN";
}
State transition(State current, Event ev, State* prev) {
if (current == FINISHED) return FINISHED; // 终态不再响应
if (ev == PAUSE && current != PAUSED) {
*prev = current;
return PAUSED;
}
if (ev == RESUME && current == PAUSED) {
return *prev;
}
if (ev == CANCEL && current != PAUSED) {
return IDLE;
}
switch(current) {
case IDLE:
if (ev == START) return FILLING;
break;
case FILLING:
if (ev == WATER_FULL) return WASHING;
break;
case WASHING:
if (ev == WASH_DONE) return RINSING;
break;
case RINSING:
if (ev == RINSE_DONE) return SPINNING;
break;
case SPINNING:
if (ev == SPIN_DONE) return FINISHED;
break;
default:
break;
}
return current; // 无效事件保持原状态
}
int main() {
State state = IDLE;
State prev = IDLE;
// 模拟一次完整洗衣流程:启动→注满→洗涤完→漂洗→脱水→结束
Event seq[] = {START, WATER_FULL, WASH_DONE, RINSE_DONE, SPIN_DONE};
int n = sizeof(seq)/sizeof(seq[0]);
printf("=== 正常流程 ===\n");
for (int i = 0; i < n; i++) {
State next = transition(state, seq[i], &prev);
printf("%-10s --%-12s--> %s\n",
state_name(state), "event", state_name(next));
state = next;
}
// 模拟暂停/继续/取消
printf("\n=== 暂停/继续/取消 ===\n");
state = IDLE;
state = transition(state, START, &prev); // IDLE→FILLING
state = transition(state, PAUSE, &prev); // FILLING→PAUSED
printf("FILLING --PAUSE--> %s\n", state_name(state));
state = transition(state, RESUME, &prev); // PAUSED→FILLING
printf("PAUSED --RESUME--> %s\n", state_name(state));
state = transition(state, CANCEL, &prev); // FILLING→IDLE
printf("FILLING --CANCEL--> %s\n", state_name(state));
return 0;
}
编译与运行
gcc -o washer_fsm washer_fsm.c
./washer_fsm
验证方法
程序输出应包含两部分:
- 正常流程:依次打印
IDLE→FILLING→WASHING→RINSING→SPINNING→FINISHED的状态迁移链; - 暂停/继续/取消:打印
FILLING→PAUSED、PAUSED→FILLING、FILLING→IDLE三条迁移结果。
若输出与上述状态链一致,且终态 FINISHED 后不再响应任何事件,则判定状态机逻辑正确。
上图展示了状态机的完整拓扑:主流程沿上方从左至右推进,PAUSE 从任意运行态进入暂停,RESUME 返回原状态,CANCEL 从任意非暂停态直接回到 IDLE,FINISHED 为终态不再响应事件。