4. 洗衣机控制状态机

任务说明

设计并实现一个洗衣机控制状态机,覆盖注水→洗涤→漂洗→脱水→结束的主流程,同时支持运行中的暂停/继续与取消操作。状态机采用经典FSM结构,通过事件驱动完成状态迁移,可直接编译运行并观察状态变化日志。

状态定义与迁移规则

当前状态触发事件动作下一状态
IDLESTART开始注水FILLING
FILLINGWATER_FULL启动电机洗涤WASHING
WASHINGWASH_DONE排水并注水RINSING
RINSINGRINSE_DONE启动脱水SPINNING
SPINNINGSPIN_DONE停机FINISHED
任意非终态PAUSE暂停当前动作PAUSED
PAUSEDRESUME恢复暂停前状态暂停前状态
任意非终态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

验证方法

程序输出应包含两部分:

  1. 正常流程:依次打印 IDLE→FILLING→WASHING→RINSING→SPINNING→FINISHED 的状态迁移链;
  2. 暂停/继续/取消:打印 FILLING→PAUSED、PAUSED→FILLING、FILLING→IDLE 三条迁移结果。

若输出与上述状态链一致,且终态 FINISHED 后不再响应任何事件,则判定状态机逻辑正确。

IDLE FILLING WASHING RINSING SPINNING FINISHED PAUSED START WATER_FULL WASH_DONE RINSE_DONE SPIN_DONE PAUSE CANCEL RESUME

上图展示了状态机的完整拓扑:主流程沿上方从左至右推进,PAUSE 从任意运行态进入暂停,RESUME 返回原状态,CANCEL 从任意非暂停态直接回到 IDLE,FINISHED 为终态不再响应事件。