Skip to content

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 段选
紧急模式按键切换,暂停正常流程

扩展方向 ​

  1. 加入行人按键:行人按下后,下一周期延长红灯让行人通过
  2. 加入蜂鸣器:黄灯期间蜂鸣提示
  3. 不同时间段(高峰/平峰)不同配时
  4. 与后文 LCEDA 部分结合,将电路做成真实 PCB 板

实验任务 ​

  1. 完成交通灯仿真(4 状态循环 + 数码管倒计时)
  2. 实现紧急模式按键切换
  3. 扩展:行人过街按钮功能

考核点 / 验收标准 ​

考核项验收标准分值
状态机设计4 状态交通灯循环时序正确30
倒计时显示数码管正确显示剩余秒数25
定时基准定时器产生准确秒基准20
紧急模式按键切换全红闪烁功能正常15
代码质量模块化设计、注释清晰10

实操要求:完整演示交通灯运行 + 紧急模式,答辩说明设计思路。

aioteer · 物联网专业课程群

💬AI 伴学配置