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() 的测试文件)。

最小验证步骤:

  1. 初始化 WasherFSM m; fsm_init(&m);,断言 m.current == IDLE。
  2. 设置 e = {.start_pressed=true, .door_locked=true},调用 fsm_run(&m, &e),断言 m.current == FILL 且 m.water_valve == true。
  3. 依次触发 water_full、wash_done、rinse_done、spin_done,每步调用后断言状态分别变为 WASH、RINSE、SPIN、END。
  4. 在 WASH 状态设置 fault_detected=true,调用后断言 m.current == FAULT 且 m.motor == false、m.door_lock_output == true。
  5. 设置 fault_cleared=true,调用后断言回到 IDLE 且门锁解锁。

通过条件:以上断言全部成立,且门锁在 FILL~SPIN 期间始终为 true,在 END 状态变为 false,故障时强制锁定。

状态迁移图

IDLE FILL WASH RINSE SPIN END FAULT start & 门锁 水满 洗涤完 漂洗完 脱水完 开门 故障 故障清除

说明:图中实线为正常流程,红色虚线为故障中断(从任意运行状态进入 FAULT),绿色虚线为故障恢复路径。门锁输出在 FILL 至 SPIN 期间保持锁定,END 状态解锁,FAULT 状态强制锁定。