内容介绍
内容介绍
项目介绍
完全使用WebIDE的图形化编程,使用常规的74系列的元器件,构建一个交通灯控制系统:
- 在数码管上显示计时信息 - 图形化
- 蜂鸣器报警 - 图形化
- 接近传感器检测人员走近 -Verilog
- 环境光感知,自动点亮路灯(小脚丫核心板上的单色LED)- Verilog
硬件介绍
STEP Baseboard4.0底板+STEP MXO2 LPC核心板
方案框图
1. 系统功能概述
- 红绿灯倒计时:系统实现红、黄、绿三色交通灯的周期性切换,并通过RGB灯显示当前交通灯的颜色状态。倒计时信息通过数码管实时显示。
- 蜂鸣器报警:在黄灯状态下,系统触发蜂鸣器报警,提醒行人和车辆注意交通安全。当接近传感器检测到人员靠近时,蜂鸣器也会触发报警。
- 接近传感器检测:系统通过接近传感器检测是否有人员靠近,并将传感器数据实时显示在数码管上。
- 环境光感知:系统通过环境光传感器检测周围光照强度,当光照较暗时,自动点亮LED灯,且光照越暗,点亮的LED灯数量越多。
2. 模块划分与功能
项目通过多个模块实现不同的功能,模块之间的调用关系如下:
- 顶层模块 (
TOP_traffic.v
): - 负责协调所有子模块的工作,连接输入输出信号。
- 调用
traffic_tube.v
、rgb_led_module.v
、beeper_ctrl.v
、rpr0521rs_driver.v
、seg_ctrl.v
、segment.v
、decoder.v
、breath_led.v
和segment_scan.v
。
- 交通灯控制模块 (
traffic_tube.v
): - 实现红绿灯倒计时控制,输出当前红绿灯状态和倒计时信息。
- 调用
bin_to_bcd.v
将倒计时秒数转换为BCD码,供数码管显示。
- RGB LED控制模块 (
rgb_led_module.v
): - 根据红绿灯状态控制RGB LED的颜色,并在黄灯状态下触发蜂鸣器报警。
- 蜂鸣器控制模块 (
beeper_ctrl.v
): - 根据接近传感器数据和蜂鸣器使能信号,控制蜂鸣器响起。
- RPR0521RS传感器驱动模块 (
rpr0521rs_driver.v
): - 通过I2C总线读取RPR0521RS传感器的环境光、红外和接近传感器数据。
- 数码管控制模块 (
seg_ctrl.v
): - 根据接近传感器数据控制数码管的使能信号。
- 数码管显示模块 (
segment.v
): - 将4位二进制数据转换为数码管的段码,控制数码管的显示。
- 数据解码模块 (
decoder.v
): - 将传感器数据转换为BCD码,便于数码管显示。
- 调用
bin_to_bcd.v
将二进制数据转换为BCD码。
- 呼吸灯控制模块 (
breath_led.v
): - 实现呼吸灯效果,控制LED的亮度逐渐变化。
- 数码管扫描模块 (
segment_scan.v
): - 控制多个数码管的动态扫描显示。
- 二进制转BCD码模块 (
bin_to_bcd.v
): - 将二进制数据转换为BCD码,便于数码管显示。
webIDE电路图及diamond关键代码说明
1.数码管控制模块
module seg_ctrl(
input wire clk, // 系统时钟输入
input rst_n, // 低有效复位信号
input [15:0] prox_dat, // 接近传感器的输入数据
input dat_valid, // 数据有效信号,表示prox_dat有效
output reg seg_en // 数码管使能信号,1表示启用数码管显示,0表示关闭
);
// 第1段:解析出稳定的prox_dat2
reg [15:0] prox_dat0, prox_dat1, prox_dat2; // 用于存储接近传感器数据的寄存器
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
// 复位时,初始化所有寄存器为0
prox_dat0 <= 16'd0;
prox_dat1 <= 16'd0;
prox_dat2 <= 16'd0;
end
else if (dat_valid) begin
// 当数据有效时,更新寄存器值
prox_dat0 <= prox_dat; // 将当前传感器数据存入prox_dat0
prox_dat1 <= prox_dat0; // 将prox_dat0的值存入prox_dat1
// 判断数据是否发生剧烈变化(防止噪声干扰)
if (((prox_dat1 - prox_dat0) >= 16'h800) || ((prox_dat1 - prox_dat0) >= 16'h800))
prox_dat2 <= prox_dat2; // 如果数据变化过大,保持prox_dat2不变
else
prox_dat2 <= prox_dat0; // 否则,更新prox_dat2为prox_dat0的值
end
else begin
// 数据无效时,保持寄存器值不变
prox_dat0 <= prox_dat0;
prox_dat1 <= prox_dat1;
prox_dat2 <= prox_dat2;
end
end
// 第2段:数码管使能控制
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
seg_en <= 1'b0; // 复位时,关闭数码管显示
else if (prox_dat2 >= 30)
seg_en <= 1'b1; // 当接近传感器数据大于等于30时,启用数码管显示
else
seg_en <= 1'b0; // 否则,关闭数码管显示
end
endmodule
2.蜂鸣器控制模块
module beeper_ctrl
(
input clk, // 时钟信号
input rst_n, // 复位信号,低电平有效
input beeper_en, // 蜂鸣器使能信号
output wire beeper, // 蜂鸣器输出信号
input [15:0] prox_dat, // 接近传感器数据输入
input dat_valid // 数据有效信号
);
// 音调频率参数定义
parameter FREQ_1 = 16'd45872; // 音调1
parameter FREQ_2 = 16'd40858; // 音调2
parameter FREQ_3 = 16'd36408; // 音调3
parameter FREQ_4 = 16'd34364; // 音调4
parameter FREQ_5 = 16'd30612; // 音调5
parameter FREQ_6 = 16'd27273; // 音调6
parameter FREQ_7 = 16'd24296; // 音调7
parameter FREQ_8 = 16'd22931; // 音调8
parameter FREQ_9 = 16'd20432; // 音调9
parameter FREQ_10 = 16'd18201; // 音调10
parameter FREQ_11 = 16'd17180; // 音调11
parameter FREQ_12 = 16'd15306; // 音调12
parameter FREQ_13 = 16'd13636; // 音调13
parameter FREQ_14 = 16'd12148; // 音调14
parameter FREQ_15 = 16'd11478; // 音调15
parameter FREQ_16 = 16'd10215; // 音调16
parameter CNT_1s_MAX = 12_000_000; // 12MHz时钟,1秒的周期
// 其他参数
parameter THRESHOLD = 100; // 距离阈值
parameter ALARM_PERIOD = 2_000_000;// 警报周期
reg beeper_state; // 蜂鸣器状态寄存器
assign beeper = beeper_state; // 将寄存器值赋给输出信号
reg [15:0] counter; // 音调计数器
reg [31:0] counter_2s; // 2秒计数器
reg [31:0] alarm_counter; // 警报计数器
reg beeper_en2; // 蜂鸣器使能信号2
reg [15:0] tone_cycle; // 音调周期
// 第一部分:解析稳定的传感器数据
reg [15:0] sensor_dat0, sensor_dat1, sensor_dat2;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
sensor_dat0 <= 16'd0;
sensor_dat1 <= 16'd0;
sensor_dat2 <= 16'd0;
end
else if(dat_valid) begin
sensor_dat0 <= prox_dat;
sensor_dat1 <= sensor_dat0;
if(((sensor_dat1 - sensor_dat0) >= 16'h800)||((sensor_dat1 - sensor_dat0) <= 16'h800))
sensor_dat2 <= sensor_dat2;
else
sensor_dat2 <= sensor_dat0;
end
else begin
sensor_dat0 <= sensor_dat0;
sensor_dat1 <= sensor_dat1;
sensor_dat2 <= sensor_dat2;
end
end
// 第二部分:音调节奏计数
always @(posedge clk or negedge rst_n)
if(!rst_n)
counter <= 1'b1;
else if(counter >= tone_cycle)
counter <= 1'b1;
else
counter <= counter + 1'b1;
// 第三部分:警报器使能计数
always @(posedge clk or negedge rst_n)
if(!rst_n)
alarm_counter <= 1'b1;
else if(sensor_dat2 > THRESHOLD)
if(alarm_counter >= ALARM_PERIOD)
alarm_counter <= 1;
else
alarm_counter <= alarm_counter + 1'b1;
else
alarm_counter <= 1;
// 第四部分:控制蜂鸣器震动
always@(posedge clk or negedge rst_n)
if(!rst_n)
beeper_state <= 1'b1;
else if(beeper_en || beeper_en2)
if(counter < tone_cycle >> 1)
beeper_state <= 1'b1;
else
beeper_state <= 1'b0;
else
beeper_state <= 1'b1;
// 第五部分:计数蜂鸣器的2秒周期
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
counter_2s <= 32'd0;
else if(beeper_en)
counter_2s <= counter_2s + 1'b1;
else
counter_2s <= 32'd0;
end
// 第六部分:模式二:有人接近时
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
beeper_en2 <= 1'b0;
else
if(sensor_dat2 >= THRESHOLD)
if(alarm_counter == ALARM_PERIOD)
beeper_en2 <= ~beeper_en2;
else
beeper_en2 <= beeper_en2;
else
beeper_en2 <= 1'b0;
end
// 第七部分:根据距离调整音调
always@(posedge clk or negedge rst_n) begin
if(!rst_n)begin
tone_cycle <= FREQ_3;
end else begin
if(sensor_dat2 <= THRESHOLD) begin tone_cycle <= FREQ_3;end
else begin tone_cycle <= FREQ_7;end
end
end
endmodule
3.RGB灯控制模块
module rgb_led_module #(
parameter CNT_1s_MAX = 12_000_000 // 12MHz时钟,1秒的周期
)
(
input clk, // 12MHz时钟输入
input rst_n, // 低有效复位信号
input [1:0] rgb_state, // RGB状态输入,用于控制LED和蜂鸣器
output [2:0] led_rgb, // RGB LED输出
output beeper_en // 蜂鸣器使能输出
);
// 内部寄存器定义
reg [2:0] led_rgb_R ; // RGB LED状态寄存器,用于驱动led_rgb输出
reg beeper_en_R ; // 蜂鸣器使能寄存器,用于驱动beeper_en输出
reg [31:0] cnt_1_4s ; // 1/4秒计数器,用于控制蜂鸣器的闪烁频率
// LED颜色定义
localparam RED_COLOR = 3'b011; // 红色LED编码
localparam GREEN_COLOR = 3'b101; // 绿色LED编码
localparam YELLOW_COLOR = 3'b110; // 黄色LED编码
// RGB状态定义
localparam GREEN_STATE = 0; // 绿色状态
localparam YELLOW_STATE = 1; // 黄色状态
localparam RED_STATE = 2; // 红色状态
// 将内部寄存器连接到输出端口
assign led_rgb = led_rgb_R;
assign beeper_en = beeper_en_R;
// 控制RGB LED的颜色
always@(posedge clk or negedge rst_n)
if(!rst_n)
led_rgb_R <= GREEN_COLOR; // 复位时,默认显示绿色
else if(rgb_state == GREEN_STATE)
led_rgb_R <= GREEN_COLOR; // 如果状态为绿色,则显示绿色
else if(rgb_state == YELLOW_STATE)
led_rgb_R <= YELLOW_COLOR; // 如果状态为黄色,则显示黄色
else
led_rgb_R <= RED_COLOR; // 其他状态显示红色
// 控制蜂鸣器的使能信号
always@(posedge clk or negedge rst_n)
if(!rst_n)
beeper_en_R <= 0; // 复位时,关闭蜂鸣器
else if(rgb_state == YELLOW_STATE) // 只有在黄色状态时才控制蜂鸣器
if(cnt_1_4s == CNT_1s_MAX >> 2) // 每1/4秒翻转一次蜂鸣器状态
beeper_en_R <= ~beeper_en_R;
else
beeper_en_R <= beeper_en_R; // 保持当前状态
else
beeper_en_R <= 0; // 其他状态关闭蜂鸣器
// 1/4秒计数器逻辑
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt_1_4s <= 0; // 复位时清零计数器
else if(rgb_state == YELLOW_STATE) // 只有在黄色状态时才计数
if(cnt_1_4s == CNT_1s_MAX >> 2) // 达到1/4秒时清零
cnt_1_4s <= 0;
else
cnt_1_4s <= cnt_1_4s + 1'b1; // 否则递增计数器
else
cnt_1_4s <= 0; // 其他状态清零计数器
endmodule
4.交通灯倒计时控制模块
module traffic_tube #(
parameter CNT_1s_MAX = 12_000_000, // 12MHz时钟,1秒的周期
parameter GREEN_MAX = 12, // 绿灯最大倒计时时间(秒)
parameter YELLOW_MAX = 4, // 黄灯最大倒计时时间(秒)
parameter RED_MAX = 11 // 红灯最大倒计时时间(秒)
)
(
input clk, // 12MHz时钟输入
input rst_n, // 低有效复位信号
output wire [3:0] sec0, // 秒的个位
output wire [3:0] sec1, // 秒的十位
output wire [1:0] rgb_state // 当前红绿灯状态输出
);
// 内部寄存器定义
reg [1:0] rgb_state_R ; // 红绿灯状态寄存器
reg [31:0] sec ; // 当前倒计时秒数
reg [23:0] counter ; // 用于12MHz时钟的24位计数器,计数到1秒
wire [31:0] bcd_code ; // 二进制转BCD码的输出
// 将红绿灯状态寄存器输出到外部
assign rgb_state = rgb_state_R;
// 定义红绿灯状态常量
localparam GREEN_STATE = 0; // 绿灯状态
localparam YELLOW_STATE = 1; // 黄灯状态
localparam RED_STATE = 2; // 红灯状态
// 主状态机逻辑,控制红绿灯状态切换和倒计时
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
// 复位时,初始化计数器、倒计时秒数和红绿灯状态
counter <= 0;
sec <= GREEN_MAX;
rgb_state_R <= GREEN_STATE;
end else if (counter == CNT_1s_MAX - 1) begin
// 当计数器达到1秒时,重置计数器并更新倒计时
counter <= 0; // 重置计数器
if (sec == 0) begin
// 当倒计时为0时,切换红绿灯状态并重置倒计时
case(rgb_state_R)
GREEN_STATE: begin sec <= YELLOW_MAX; rgb_state_R <= YELLOW_STATE; end // 绿灯状态切换到黄灯状态
YELLOW_STATE: begin sec <= RED_MAX; rgb_state_R <= RED_STATE; end // 黄灯状态切换到红灯状态
RED_STATE: begin sec <= GREEN_MAX; rgb_state_R <= GREEN_STATE; end // 红灯状态切换到绿灯状态
endcase
end else begin
sec <= sec - 1; // 倒计时减1
end
end else begin
counter <= counter + 1; // 计数器递增
end
end
// 实例化二进制转BCD码模块,将倒计时秒数转换为BCD码
bin_to_bcd u1_bin_to_bcd
(
.rst_n (rst_n ), // 复位信号
.bin_code (sec ), // 输入的二进制秒数
.bcd_code (bcd_code ) // 输出的BCD码
);
// 将BCD码的个位和十位分别输出
assign sec0 = bcd_code[3:0]; // 秒的个位
assign sec1 = bcd_code[7:4]; // 秒的十位
endmodule
5.呼吸灯控制模块
module breath_led(
input sys_clk , //系统时钟 50MHz
input sys_rst_n , //系统复位,低电平有效
output reg led //LED灯
// output reg led_fan
);
//parameter define
parameter CNT_2US_MAX = 7'd24;
parameter CNT_2MS_MAX = 10'd1000;
parameter CNT_2S_MAX = 10'd1000;
//reg define
reg [6:0] cnt_2us;
reg [9:0] cnt_2ms;
reg [9:0] cnt_2s;
reg inc_dec_flag; //亮度递增/递减 0:递增 1:递减
//cnt_2us:计数2us
always@(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
cnt_2us <= 7'b0;
else if(cnt_2us == (CNT_2US_MAX - 7'b1 ))
cnt_2us <= 7'b0;
else
cnt_2us <= cnt_2us + 7'b1;
end
//cnt_2ms:计数2ms
always@(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
cnt_2ms <= 10'b0;
else if(cnt_2ms == (CNT_2MS_MAX - 10'b1) && cnt_2us == (CNT_2US_MAX - 7'b1))
cnt_2ms <= 10'b0;
else if(cnt_2us == CNT_2US_MAX - 7'b1)
cnt_2ms <= cnt_2ms + 10'b1;
else
cnt_2ms <= cnt_2ms;
end
//cnt_2s:计数2s
always@(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
cnt_2s <= 10'b0;
else if(cnt_2s == (CNT_2S_MAX - 10'b1) && cnt_2ms == (CNT_2MS_MAX - 10'b1) && cnt_2us == (CNT_2US_MAX - 7'b1))
cnt_2s <= 10'b0;
else if(cnt_2ms == (CNT_2MS_MAX - 10'b1) && cnt_2us == (CNT_2US_MAX - 7'b1))
cnt_2s <= cnt_2s + 10'b1;
else
cnt_2s <= cnt_2s;
end
//inc_dec_flag为低电平,led灯由暗变亮,inc_dec_flag为高电平,led灯由亮变暗
always@(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
inc_dec_flag <= 1'b0;
else if(cnt_2s == (CNT_2S_MAX - 10'b1) && cnt_2ms ==( CNT_2MS_MAX - 10'b1) && cnt_2us == (CNT_2US_MAX - 7'b1))
inc_dec_flag <= ~inc_dec_flag;
else
inc_dec_flag <= inc_dec_flag;
end
//led:输出信号连接到外部的led灯
always@(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
led <= 1'b0;
else if((inc_dec_flag == 1'b1 && cnt_2ms >= cnt_2s) || (inc_dec_flag == 1'b0 && cnt_2ms <= cnt_2s))
led <= 1'b1;
else
led <= 1'b0;
end
endmodule
功能展示图
- 功能描述:系统实现红、黄、绿三色交通灯的周期性切换,并通过RGB灯显示当前交通灯的颜色状态。每个颜色的持续时间通过倒计时显示,倒计时信息通过数码管实时展示。
- 技术实现:
- 使用Verilog设计状态机,控制红、黄、绿灯的切换逻辑。
- 倒计时信息通过数码管显示。
- RGB灯根据当前交通灯状态显示相应颜色。
- 功能描述:当交通灯切换到黄灯状态时,系统自动触发蜂鸣器报警,提醒行人和车辆注意交通安全。
- 技术实现:
- 在webIDE中设计黄灯状态的检测逻辑,当状态切换到黄灯时,触发蜂鸣器控制信号。
- 功能描述:系统通过接近传感器检测是否有人员靠近。当检测到人员接近时,触发蜂鸣器报警,并将传感器输出的数值实时显示在底板的数码管上。
- 技术实现:
- 使用Verilog处理接近传感器的数据,通过滤波和阈值判断,确保检测结果的准确性。
- 传感器数据经过处理后,转换为BCD码并显示在数码管上。
- 当检测到人员接近时,系统触发蜂鸣器报警,提醒相关人员注意。
- 功能描述:系统通过环境光传感器检测周围光照强度。当光照较暗时,自动点亮LED灯,且光照越暗,点亮的LED灯数量越多。
- 技术实现:
- 使用Verilog处理环境光传感器的数据,根据光照强度划分多个阈值区间。
- 每个阈值区间对应点亮的LED灯数量,光照越暗,点亮的LED灯数量越多。
- LED灯的点亮逻辑通过Verilog代码实现,确保光照变化时LED灯的亮度能够动态调整。
难题及解决方法
- 难题:图形化编程和Verilog代码的协同工作存在一定的难度,尤其是在数据传递和控制逻辑的同步上,容易出现不一致的情况。
- 解决方法:
- 接口定义:在项目初期,明确定义了图形化编程模块与Verilog模块之间的接口,确保数据传递的准确性和一致性。
- 模块化设计:将图形化编程和Verilog代码分别设计为独立的模块,每个模块只负责特定的功能,通过清晰的接口进行通信,确保协同工作的稳定性。
心得体会
体会到了图形化编程的乐趣,但是希望webIDE的界面可以做的更好。
WebIDE链接
资源占用报告
附件下载
TOP_impl1.jed
jed文件,可直接烧录
archive.rar
项目文件,内部archive1.rar是webIDE的导出结果
团队介绍
学生
团队成员
adachi
评论
0 / 100
查看更多
猜你喜欢
2025寒假练-基于小脚丫FPGA实现交通灯控制系统该项目使用了小脚丫FPGA,实现了交通灯控制系统的设计,它的主要功能为:在数码管上显示计时信息、蜂鸣器报警、接近传感器检测人员走近和环境光感知,自动点亮路灯。。
cdh
33
2025寒假练 - 基于小脚丫FPGA实现交通灯控制系统该项目使用了小脚丫FPGA,Diamond软件,WebIDE,Verilog语言,实现了交通灯控制系统的设计,它的主要功能为:在数码管上显示计时信息,蜂鸣器报警,接近传感器检测人员走近,环境光感知,自动点亮路灯。
BNumerator
26
2025寒假练 - 基于小脚丫FPGA实现交通灯控制系统该项目使用了STEP Baseboard4.0底板和STEP MXO2 LPC核心板;WebIDE的图形化编程和Diamond,实现了一个交通灯控制系统的设计,它的主要功能为:以20秒为一个红绿灯变换周期进行计时,在红灯向绿灯的转变过程中,蓝光短暂亮起进行过渡,同时蜂鸣器报警。在检测到人员靠近和环境过暗时,自动亮起单色LED。。
xjxxjxxjx
25