1. 交通信号灯控制器

交通信号灯控制器 学习卡片

任务目标

设计一个三状态有限状态机(FSM),实现交通信号灯的红灯→绿灯→黄灯→红灯循环切换。每个状态持续固定时长,状态迁移由定时器驱动,不依赖外部输入。

核心设计

采用Moore型FSM,输出仅由当前状态决定。三个状态及持续时间:红灯30秒 → 绿灯25秒 → 黄灯5秒,循环往复。使用状态编号0/1/2表示,通过一个周期计数器实现定时迁移。

完整实现(C语言)

#include <stdio.h>
#include <unistd.h>   // sleep()
#include <stdbool.h>

// 状态定义
typedef enum {
    RED = 0,
    GREEN = 1,
    YELLOW = 2
} LightState;

// 各状态持续时间(秒)
const int DURATION[3] = {30, 25, 5};

// 状态对应的灯输出描述
const char* LIGHT_NAME[3] = {"红灯", "绿灯", "黄灯"};

// 状态迁移函数:返回下一个状态
LightState next_state(LightState cur) {
    return (LightState)((cur + 1) % 3);
}

int main() {
    LightState state = RED;   // 初始状态:红灯
    int elapsed = 0;          // 当前状态已持续秒数

    printf("交通信号灯FSM启动(红灯30s → 绿灯25s → 黄灯5s)\n\n");

    // 模拟运行一个完整周期(60秒)
    for (int t = 0; t < 60; t++) {
        // 输出当前秒的状态
        printf("[%2d秒] %s(已持续%d秒,剩余%d秒)\n",
               t + 1,
               LIGHT_NAME[state],
               elapsed + 1,
               DURATION[state] - elapsed - 1);

        // 判断是否需要迁移
        elapsed++;
        if (elapsed >= DURATION[state]) {
            state = next_state(state);
            elapsed = 0;
        }

        sleep(1);   // 实际运行时每秒更新一次
    }

    printf("\n完成一个完整周期(60秒)的模拟。\n");
    return 0;
}

运行方式

  1. 将代码保存为 traffic_light_fsm.c
  2. 编译:gcc -o traffic_light_fsm traffic_light_fsm.c
  3. 运行:./traffic_light_fsm

验证方法

程序运行后每秒打印一次当前灯色及剩余时间。观察输出应满足:

  • 第1~30秒输出红灯,剩余时间从29递减到0
  • 第31~55秒输出绿灯,剩余时间从24递减到0
  • 第56~60秒输出黄灯,剩余时间从4递减到0
  • 第61秒起循环回到红灯(若继续运行)

状态迁移严格按RED → GREEN → YELLOW → RED顺序循环,无跳变或卡死,即判定通过。

状态迁移图

红灯 30秒 绿灯 25秒 黄灯 5秒 超时 超时 超时

关键说明

  • 状态迁移仅由计时器(elapsed计数器)触发,无外部输入事件,属于典型的时间驱动FSM。
  • 若需接入真实硬件(如Arduino),将sleep(1)替换为开发板的延时函数,并将灯色输出映射到对应GPIO引脚即可。
  • 修改DURATION数组即可调整各灯时长,无需改动状态机逻辑。