4. 洗衣机程序
任务目标
设计一个洗衣机控制程序的状态机,包含注水、洗涤、漂洗、脱水四个核心状态,并支持暂停与取消操作。程序需能响应启动、暂停/继续、取消等外部事件,并在每个状态中模拟对应动作的执行。
状态与事件定义
洗衣机FSM包含以下状态与事件:
- 状态:IDLE(待机)、FILL(注水)、WASH(洗涤)、RINSE(漂洗)、SPIN(脱水)、PAUSED(暂停)
- 事件:START(启动)、PAUSE(暂停)、RESUME(继续)、CANCEL(取消)、COMPLETE(当前阶段完成)
状态转移规则:
- IDLE + START → FILL
- FILL + COMPLETE → WASH;FILL + PAUSE → PAUSED;FILL + CANCEL → IDLE
- WASH + COMPLETE → RINSE;WASH + PAUSE → PAUSED;WASH + CANCEL → IDLE
- RINSE + COMPLETE → SPIN;RINSE + PAUSE → PAUSED;RINSE + CANCEL → IDLE
- SPIN + COMPLETE → IDLE(洗涤结束);SPIN + PAUSE → PAUSED;SPIN + CANCEL → IDLE
- PAUSED + RESUME → 返回暂停前的状态;PAUSED + CANCEL → IDLE
完整实现代码
#include <stdio.h>
#include <stdlib.h>
typedef enum {
IDLE, FILL, WASH, RINSE, SPIN, PAUSED
} State;
typedef enum {
START, PAUSE, RESUME, CANCEL, COMPLETE
} Event;
typedef struct {
State current;
State paused_from; // 记录暂停前的状态
} WasherFSM;
const char* state_name(State s) {
switch (s) {
case IDLE: return "待机";
case FILL: return "注水";
case WASH: return "洗涤";
case RINSE: return "漂洗";
case SPIN: return "脱水";
case PAUSED: return "暂停";
default: return "未知";
}
}
void init_fsm(WasherFSM* fsm) {
fsm->current = IDLE;
fsm->paused_from = IDLE;
}
void handle_event(WasherFSM* fsm, Event ev) {
State s = fsm->current;
switch (s) {
case IDLE:
if (ev == START) {
fsm->current = FILL;
printf("启动:开始注水\n");
}
break;
case FILL:
if (ev == COMPLETE) {
fsm->current = WASH;
printf("注水完成,开始洗涤\n");
} else if (ev == PAUSE) {
fsm->paused_from = FILL;
fsm->current = PAUSED;
printf("注水阶段暂停\n");
} else if (ev == CANCEL) {
fsm->current = IDLE;
printf("已取消,回到待机\n");
}
break;
case WASH:
if (ev == COMPLETE) {
fsm->current = RINSE;
printf("洗涤完成,开始漂洗\n");
} else if (ev == PAUSE) {
fsm->paused_from = WASH;
fsm->current = PAUSED;
printf("洗涤阶段暂停\n");
} else if (ev == CANCEL) {
fsm->current = IDLE;
printf("已取消,回到待机\n");
}
break;
case RINSE:
if (ev == COMPLETE) {
fsm->current = SPIN;
printf("漂洗完成,开始脱水\n");
} else if (ev == PAUSE) {
fsm->paused_from = RINSE;
fsm->current = PAUSED;
printf("漂洗阶段暂停\n");
} else if (ev == CANCEL) {
fsm->current = IDLE;
printf("已取消,回到待机\n");
}
break;
case SPIN:
if (ev == COMPLETE) {
fsm->current = IDLE;
printf("脱水完成,洗衣结束\n");
} else if (ev == PAUSE) {
fsm->paused_from = SPIN;
fsm->current = PAUSED;
printf("脱水阶段暂停\n");
} else if (ev == CANCEL) {
fsm->current = IDLE;
printf("已取消,回到待机\n");
}
break;
case PAUSED:
if (ev == RESUME) {
fsm->current = fsm->paused_from;
printf("继续:回到%s阶段\n", state_name(fsm->current));
} else if (ev == CANCEL) {
fsm->current = IDLE;
printf("已取消,回到待机\n");
}
break;
}
}
int main() {
WasherFSM washer;
init_fsm(&washer);
// 模拟一次完整洗衣流程:启动→注水→暂停→继续→洗涤→漂洗→脱水→结束
handle_event(&washer, START); // 待机 → 注水
handle_event(&washer, COMPLETE); // 注水 → 洗涤
handle_event(&washer, PAUSE); // 洗涤 → 暂停
handle_event(&washer, RESUME); // 暂停 → 洗涤
handle_event(&washer, COMPLETE); // 洗涤 → 漂洗
handle_event(&washer, COMPLETE); // 漂洗 → 脱水
handle_event(&washer, COMPLETE); // 脱水 → 待机
printf("\n--- 测试取消功能 ---\n");
init_fsm(&washer);
handle_event(&washer, START); // 待机 → 注水
handle_event(&washer, CANCEL); // 注水 → 待机
return 0;
}
编译与运行
gcc -o washer_fsm washer_fsm.c
./washer_fsm
验证方法
程序运行后,观察输出是否符合以下预期流程:
- 启动后进入注水状态,输出“启动:开始注水”
- 注水完成后进入洗涤,输出“注水完成,开始洗涤”
- 洗涤中暂停输出“洗涤阶段暂停”,继续后输出“继续:回到洗涤阶段”
- 依次完成洗涤、漂洗、脱水,最终输出“脱水完成,洗衣结束”
- 取消测试中,注水阶段取消后输出“已取消,回到待机”
若输出与上述顺序一致,且程序正常退出(无崩溃),则判定FSM逻辑正确。