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;
}
运行方式
- 将代码保存为
traffic_light_fsm.c - 编译:
gcc -o traffic_light_fsm traffic_light_fsm.c - 运行:
./traffic_light_fsm
验证方法
程序运行后每秒打印一次当前灯色及剩余时间。观察输出应满足:
- 第1~30秒输出红灯,剩余时间从29递减到0
- 第31~55秒输出绿灯,剩余时间从24递减到0
- 第56~60秒输出黄灯,剩余时间从4递减到0
- 第61秒起循环回到红灯(若继续运行)
状态迁移严格按RED → GREEN → YELLOW → RED顺序循环,无跳变或卡死,即判定通过。
状态迁移图
关键说明
- 状态迁移仅由计时器(elapsed计数器)触发,无外部输入事件,属于典型的时间驱动FSM。
- 若需接入真实硬件(如Arduino),将
sleep(1)替换为开发板的延时函数,并将灯色输出映射到对应GPIO引脚即可。 - 修改
DURATION数组即可调整各灯时长,无需改动状态机逻辑。