交通灯控制器课程设计
设计任务与要求
1 设计任务 设计一个十字路口的交通灯控制系统,用于主干道(A方向)和支干道(B方向)的车辆与行人通行。
2 具体功能要求

-
基本功能:
- 主干道(A方向): 通行时间较长,设有绿灯、黄灯。
- 支干道(B方向): 通行时间较短,设有绿灯、黄灯。
- 行人过街信号: 分别为主干道和支干道的行人设置红绿灯,行人绿灯亮时,对应车道的车灯必须为红灯。
- 正常时序循环:
- 状态1(主干道通行): A方向车绿灯亮,B方向车红灯亮,A方向行人红灯亮,B方向行人绿灯亮。
- 状态2(主干道过渡): A方向车黄灯亮,B方向车红灯亮,A方向行人红灯亮,B方向行人绿灯亮(黄灯亮时,行人绿灯通常保持不变或闪烁,这里简化为保持)。
- 状态3(支干道通行): A方向车红灯亮,B方向车绿灯亮,A方向行人绿灯亮,B方向行人红灯亮。
- 状态4(支干道过渡): A方向车红灯亮,B方向车黄灯亮,A方向行人绿灯亮,B方向行人红灯亮。
- 系统能够按照上述状态自动循环。
-
扩展功能(可选,用于提高设计难度和完整性):
- 紧急车辆优先: 当有紧急车辆(如消防车、救护车)通过时,两个方向的车灯全部变为红灯,以便紧急车辆快速通过,可以使用一个外部中断按键来模拟。
- 手动切换模式: 在特定情况下(如夜间车流量少),可以手动将系统切换到“闪烁黄灯”模式,提醒车辆慢行。
- 倒计时显示: 使用数码管或LED点阵显示当前状态剩余的秒数,增强人机交互性。
-
技术指标:
- 时钟频率: 使用实验箱提供的时钟信号(如1Hz或4Hz)。
- 绿灯时间: 主干道绿灯 45秒,支干道绿灯 25秒。
- 黄灯时间: 两个方向的黄灯均为 5秒。
- 输出驱动: 能驱动LED指示灯。
方案论证与选择
1 核心思想 交通灯控制器的核心是一个状态机,系统在不同时间处于不同的状态,每个状态对应一组特定的灯亮或灭,控制器的作用就是在时钟的驱动下,按照预设的时序,从一个状态平稳地切换到下一个状态。

2 实现方案对比
| 方案 | 优点 | 缺点 | 适用性 |
|---|---|---|---|
| 纯计数器方案 | 设计简单,逻辑清晰,易于理解,对于固定时序的系统非常可靠。 | 灵活性差,若需修改时间,需重新设计计数器,扩展功能(如紧急模式)实现较复杂。 | 非常适合作为课程设计的入门方案,能很好地掌握时序逻辑设计。 |
| 微控制器/单片机方案 | 功能强大,灵活性极高,编程实现简单,易于添加复杂功能(如倒计时显示、串口通信)。 | 需要软件编程知识,偏离了“数字逻辑”课程设计的初衷(硬件描述语言/逻辑门电路)。 | 适合电子综合设计或嵌入式系统课程,不适合本课程。 |
| 状态机 + 可编程逻辑器件 | 灵活性介于前两者之间,可以修改代码来改变时序,是现代数字设计的标准方法。 | 需要掌握硬件描述语言(如Verilog/VHDL)和EDA工具。 | 本课程设计的最佳选择,既能体现硬件设计的思想,又具备现代设计的灵活性。 |
3 方案选择 我们选择方案1(纯计数器方案)作为基础,并采用方案3(状态机 + HDL)的实现方式,这样既能保证设计的严谨性,又能通过代码的修改轻松调整时间参数,并方便地加入扩展功能。
详细设计
1 系统总体框图
+-----------------+
| 时钟源 | (如 1Hz)
+-------+---------+
|
v
+-------+---------+
| 控制器 | <----+
| (状态机+计数器) | |
+-------+---------+ |
| |
v (控制信号) |
+-------+---------+ |
| 译码驱动 | |
| (LED灯显示电路) | |
+-------+---------+ |
| |
v (输出) |
+-------+---------+ |
| 交通灯 | |
| (车灯, 人灯) | |
+-----------------+ |
^ |
+-------+---------+ |
| 紧急信号 | (按键/中断)
+-----------------+
2 状态机设计

我们将系统划分为4个主要状态。
| 状态名 | 车A | 车B | 人A | 人B | 持续时间 |
|---|---|---|---|---|---|
S_A_GREEN |
绿 | 红 | 红 | 绿 | 45s |
S_A_YELLOW |
黄 | 红 | 红 | 绿 | 5s |
S_B_GREEN |
红 | 绿 | 绿 | 红 | 25s |
S_B_YELLOW |
红 | 黄 | 绿 | 红 | 5s |
- 状态编码:使用2位二进制编码。
S_A_GREEN=00S_A_YELLOW=01S_B_GREEN=10S_B_YELLOW=11
3 模块划分(Verilog HDL实现)
我们可以将整个系统划分为以下几个模块:
- 顶层模块 (
traffic_light_top): 例化所有子模块,连接输入输出。 - 状态机控制模块 (
state_machine): 核心控制逻辑。- 包含一个状态寄存器(
reg [1:0] current_state, next_state)。 - 包含一个计时器(
reg [5:0] timer)。 - 状态转移逻辑:
always @(posedge clk),根据当前状态和计时器值决定下一个状态。 - 计时逻辑:
always @(posedge clk),在每个时钟周期递增计时器,并在状态切换时清零。
- 包含一个状态寄存器(
- 紧急模式处理模块 (
emergency_handler): (可选)- 检测紧急信号(
emergency)。 - 如果有紧急信号,强制状态机进入一个“全红灯”状态,直到紧急信号解除。
- 检测紧急信号(
- 输出译码模块 (
decoder):- 根据当前状态
current_state,译码出控制8个灯(车A绿/黄/红,车B绿/黄/红,人A绿/红,人B绿/红)的控制信号。
- 根据当前状态
Verilog HDL 代码示例 (基础版)
// traffic_light.v
`timescale 1ns / 1ps
module traffic_light(
input clk, // 1Hz 时钟信号
input reset_n, // 低电平复位
output reg car_a_g, // 主干道车绿灯
output reg car_a_y, // 主干道车黄灯
output reg car_a_r, // 主干道车红灯
output reg car_b_g, // 支干道车绿灯
output reg car_b_y, // 支干道车黄灯
output reg car_b_r, // 支干道车红灯
output reg ped_a_g, // 主干道人绿灯
output reg ped_a_r, // 主干道人红灯
output reg ped_b_g, // 支干道人绿灯
output reg ped_b_r // 支干道人红灯
);
// 定义状态编码
parameter S_A_GREEN = 2'b00;
parameter S_A_YELLOW = 2'b01;
parameter S_B_GREEN = 2'b10;
parameter S_B_YELLOW = 2'b11;
// 定义时间参数 (单位: 秒)
parameter T_A_GREEN = 45;
parameter T_A_YELLOW = 5;
parameter T_B_GREEN = 25;
parameter T_B_YELLOW = 5;
// 内部信号
reg [1:0] current_state, next_state;
reg [5:0] timer; // 6位计数器,最大可计数63秒,足够用
// 状态寄存器
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
current_state <= S_A_GREEN;
end else begin
current_state <= next_state;
end
end
// 计时器逻辑
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
timer <= 6'd0;
end else if (current_state != next_state) begin
timer <= 6'd0; // 状态切换时,计时器清零
end else begin
timer <= timer + 1; // 每个时钟周期加1
end
end
// 状态转移逻辑 (组合逻辑)
always @(*) begin
next_state = current_state; // 默认保持当前状态
case (current_state)
S_A_GREEN: begin
if (timer == T_A_GREEN - 1) begin // 计时到T_A_GREEN-1,下一个时钟周期切换
next_state = S_A_YELLOW;
end
end
S_A_YELLOW: begin
if (timer == T_A_YELLOW - 1) begin
next_state = S_B_GREEN;
end
end
S_B_GREEN: begin
if (timer == T_B_GREEN - 1) begin
next_state = S_B_YELLOW;
end
end
S_B_YELLOW: begin
if (timer == T_B_YELLOW - 1) begin
next_state = S_A_GREEN;
end
end
default: next_state = S_A_GREEN;
endcase
end
// 输出译码逻辑 (组合逻辑)
always @(*) begin
// 默认所有灯灭,避免锁存器
car_a_g = 1'b0;
car_a_y = 1'b0;
car_a_r = 1'b0;
car_b_g = 1'b0;
car_b_y = 1'b0;
car_b_r = 1'b0;
ped_a_g = 1'b0;
ped_a_r = 1'b0;
ped_b_g = 1'b0;
ped_b_r = 1'b0;
case (current_state)
S_A_GREEN: begin // 主干道通行
car_a_g = 1'b1;
car_b_r = 1'b1;
ped_a_r = 1'b1;
ped_b_g = 1'b1;
end
S_A_YELLOW: begin // 主干道过渡
car_a_y = 1'b1;
car_b_r = 1'b1;
ped_a_r = 1'b1;
ped_b_g = 1'b1;
end
S_B_GREEN: begin // 支干道通行
car_a_r = 1'b1;
car_b_g = 1'b1;
ped_a_g = 1'b1;
ped_b_r = 1'b1;
end
S_B_YELLOW: begin // 支干道过渡
car_a_r = 1'b1;
car_b_y = 1'b1;
ped_a_g = 1'b1;
ped_b_r = 1'b1;
end
endcase
end
endmodule
仿真与验证
1 仿真工具 使用 ModelSim, Vivado, Quartus 等 EDA 工具进行行为级或时序仿真。
1 测试平台 (Testbench) 思路
- 生成时钟和复位信号:在
initial块中定义。 - 实例化被测模块:将上面的
traffic_light模例化。 - 编写激励:
- 先进行复位操作。
- 然后等待足够长的时间,观察
current_state和timer的变化,以及各个输出引脚的信号是否按预期时序变化。 - 检查点:
S_A_GREEN状态是否持续 45 个时钟周期?- 之后是否切换到
S_A_YELLOW? S_A_YELLOW状态是否持续 5 个时钟周期?- 之后是否切换到
S_B_GREEN? - ...如此循环往复,检查所有状态。
2 硬件验证
- 引脚锁定:在 Quartus/Vivado 中,将设计中的输入输出信号(
clk,reset_n,car_a_g...)锁定到 FPGA 开发板或实验箱的实际物理引脚上。 - 下载配置:将生成的
.sof或.bit文件下载到 FPGA 芯片中。 - 观察结果:通过开发板上的 LED 指示灯观察交通灯的运行情况,看是否符合设计要求。
扩展功能设计思路
1 紧急车辆优先
- 增加输入:增加一个输入
emergency。 - 修改状态机:增加一个
S_EMERGENCY状态(编码为2'bxx)。 - 修改转移逻辑:在
always @(*)块中,emergency为高电平,则无条件将next_state设为S_EMERGENCY。 - 修改输出逻辑:在
S_EMERGENCY状态下,所有车灯(car_a_g/y/r,car_b_g/y/r)都输出红灯,行人灯保持不变或全灭。 - 退出条件:当
emergency信号变为低电平时,状态机应从S_EMERGENCY切换到之前的状态,可以增加一个prev_state寄存器来记录进入紧急前的状态。
2 倒计时显示
- 增加模块:增加一个
BCD_Driver模块,将6位的计时器timer转换成两位 BCD 码(十位和个位)。 - 增加输出:增加8个输出,用于驱动两个7段数码管(分别显示十位和个位)。
- 连接:将
timer的值连接到BCD_Driver的输入,再将BCD_Driver的输出连接到顶层模块的数码管引脚。
设计总结
本设计成功地实现了一个基于有限状态机的十字路口交通灯控制器,通过采用 Verilog HDL 进行硬件描述,设计具有结构清晰、易于修改和扩展的优点。
- 优点:方案可靠,时序精确,完全符合数字逻辑课程设计的要求,并锻炼了状态机设计、模块化编程和仿真验证的能力。
- 不足与展望:基础版本功能相对简单,未来可以进一步研究更复杂的交通流模型,例如根据传感器检测到的车流量动态调整绿灯时间,这将引入更复杂的控制算法,是很好的深化方向。
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。