1.9 综合项目:交通灯控制器
学习目标:综合运用定时器、中断、LED 控制、数码管显示,设计一个十字路口交通灯控制器。
项目需求
设计一个十字路口交通灯控制器,功能要求:
- 东西、南北两个方向各三色灯(红/黄/绿)
- 定时循环:绿灯 10s → 黄灯 2s → 红灯 12s
- 用数码管倒计时显示
- 通过按键可切换为"紧急模式"(全红闪烁)
状态机设计
十字路口交通灯状态循环(考虑两个方向状态互斥):
状态1:东西绿 + 南北红(10s)
↓
状态2:东西黄 + 南北红(2s)
↓
状态3:东西红 + 南北绿(10s)
↓
状态4:东西红 + 南北黄(2s)
↓
循环回 状态1电路设计
AT89C51
┌──────┐
│ P1.0 ├──东西红
│ P1.1 ├──东西黄
│ P1.2 ├──东西绿
│ P1.3 ├──南北红
│ P1.4 ├──南北黄
│ P1.5 ├──南北绿
│ P2 ├──4位共阳数码管(倒计时显示)
│ P3.2 ├──按键(紧急模式)
└──────┘程序设计
主程序框架
c
/****************************************************
* 项目名称:交通灯控制器
****************************************************/
#include <reg51.h>
// 端口位定义
sbit EW_R = P1^0; // 东西红灯
sbit EW_Y = P1^1; // 东西黄灯
sbit EW_G = P1^2; // 东西绿灯
sbit NS_R = P1^3; // 南北红灯
sbit NS_Y = P1^4; // 南北黄灯
sbit NS_G = P1^5; // 南北绿灯
sbit KEY = P3^2; // 紧急模式按键
// 共阳极 0~9 段码
code unsigned char seg[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99,
0x92, 0x82, 0xF8, 0x80, 0x90
};
unsigned char second = 0; // 当前倒计时秒数
unsigned char mode = 0; // 交通灯状态
unsigned char urgent = 0; // 紧急模式标志
// 定时器0:每50ms中断,累计到1s
void timer0_isr(void) interrupt 1
{
static unsigned char cnt = 0;
TH0 = 0x3C; TL0 = 0xB0;
cnt++;
if (cnt >= 20) // 1秒
{
cnt = 0;
if (second > 0) second--;
else { // 倒计时结束,切换状态
mode = (mode + 1) % 4;
set_light(mode);
}
}
}
// 设置各方向灯状态
void set_light(unsigned char m)
{
switch (m)
{
case 0: // 东西绿+南北红
EW_R=0; EW_Y=1; EW_G=0;
NS_R=0; NS_Y=1; NS_G=1;
second = 10; break;
case 1: // 东西黄+南北红
EW_R=0; EW_Y=0; EW_G=1;
NS_R=0; NS_Y=1; NS_G=1;
second = 2; break;
case 2: // 东西红+南北绿
EW_R=0; EW_Y=1; EW_G=1;
NS_R=0; NS_Y=1; NS_G=0;
second = 10; break;
case 3: // 东西红+南北黄
EW_R=0; EW_Y=1; EW_G=1;
NS_R=0; NS_Y=0; NS_G=1;
second = 2; break;
}
}
// 数码管动态显示倒计时(个位)
void display(void)
{
P2 = ~0x01; // 选中个位
P0 = seg[second % 10]; // 显示个位
}
// 主程序
void main(void)
{
TMOD = 0x01; // 定时器0方式1
TH0 = 0x3C; TL0 = 0xB0;
ET0 = 1; EA = 1; TR0 = 1;
P0 = 0xFF; P1 = 0xFF;
mode = 0; set_light(mode); // 初始状态
while (1)
{
display(); // 刷新数码管
if (KEY == 0) // 紧急模式
{
urgent = ~urgent;
if (urgent)
{
TR0 = 0; // 暂停定时
EW_R=0; NS_R=0; // 全红
EW_Y=1; EW_G=1; NS_Y=1; NS_G=1;
}
else { TR0 = 1; }
}
}
}说明:上述为教学演示框架,完整工程请结合前面各实验的知识点补充完善(如数码管多位显示、按键消抖等)。
设计要点
| 设计点 | 说明 |
|---|---|
| 状态机 | 用 mode 变量管理 4 个交通状态,逻辑清晰 |
| 定时基准 | 定时器 0 产生 50ms 时基,累加 20 次得 1s |
| 倒计时 | second 变量递减,归零切换状态 |
| 动态扫描 | 数码管用 P2 位选 + P0 段选 |
| 紧急模式 | 按键切换,暂停正常流程 |
扩展方向
- 加入行人按键:行人按下后,下一周期延长红灯让行人通过
- 加入蜂鸣器:黄灯期间蜂鸣提示
- 不同时间段(高峰/平峰)不同配时
- 与后文 LCEDA 部分结合,将电路做成真实 PCB 板
实验任务
- 完成交通灯仿真(4 状态循环 + 数码管倒计时)
- 实现紧急模式按键切换
- 扩展:行人过街按钮功能
考核点 / 验收标准
| 考核项 | 验收标准 | 分值 |
|---|---|---|
| 状态机设计 | 4 状态交通灯循环时序正确 | 30 |
| 倒计时显示 | 数码管正确显示剩余秒数 | 25 |
| 定时基准 | 定时器产生准确秒基准 | 20 |
| 紧急模式 | 按键切换全红闪烁功能正常 | 15 |
| 代码质量 | 模块化设计、注释清晰 | 10 |
实操要求:完整演示交通灯运行 + 紧急模式,答辩说明设计思路。