一、项目介绍
基于小脚丫FPGA STEP BaseBoard V4.0套件实现的红绿灯系统,是一个融合智能感知与动态显示的交通控制解决方案。该系统通过硬件编程与传感器协同工作。在小脚丫FPGA STEP BaseBoard V4.0套件上模拟实现。
二、硬件介绍
项目基于STEP BaseBoard V4.0扩展底板和小脚丫STEP-MXO2 FPGA核心板,硬件资源包括:
- 传感器模块:温湿度传感器、接近式传感器、矩阵键盘、旋转编码器等。
- 显示模块:8位7段数码管、RGB LCD液晶屏、HDMI接口。
- 通信模块:UART串口、WIFI(ESP8266)、ADC/DAC功能模块。
- 核心板:Lattice MXO2-4000HC FPGA芯片。
三、项目设计思路及代码讲解
项目 一
完成任务 1.在数码管上显示计时信息;2.蜂鸣器报警
将其结合为一个简易红绿灯系统
项目设计框图
FPGA资源占用报告
WEBIDE图形化项目连接:https://www.stepfpga.com/project/17064/gui?type=top
1.内部设备定义
状态机定义:
红绿灯系统为标准的时序电路,使用状态机约束时序电路运行逻辑
将红绿灯系统定义3个时序 红灯 绿灯 黄灯
// 状态定义
parameter RED = 2'b00;
parameter GREEN = 2'b01;
parameter YELLOW = 2'b10;
2.数码管定义
使用数码管作为倒计时数值输出,需定义不同位数的数字输出
// 八段码编码表
reg [8:0] seg_table [0:9];
initial begin
seg_table[0] = 9'h3F; // 0
seg_table[1] = 9'h06; // 1
seg_table[2] = 9'h5B; // 2
seg_table[3] = 9'h4F; // 3
seg_table[4] = 9'h66; // 4
seg_table[5] = 9'h6D; // 5
seg_table[6] = 9'h7D; // 6
seg_table[7] = 9'h07; // 7
seg_table[8] = 9'h7F; // 8
seg_table[9] = 9'h6F; // 9
end
3.时钟定义
倒计时使用1秒作为时钟的最小单位,对输入的12MHz时钟进行分频,得到标准一秒时钟单位
// 时钟分频
wire sec_pulse = (main_cnt == 24'd11_999_999); // 1秒脉冲
4.蜂鸣器定义
在绿灯过程,蜂鸣器全程鸣叫,督促行人快速经过
// 蜂鸣器控制(2Hz方波)
always @(posedge clk) begin
buzz_cnt <= (buzz_cnt == 24'd2_999_999) ? 1'd0 : buzz_cnt + 1'd1;
end
5.状态机进程流转
- 1 首先进入00状态及红灯状态
- 现象为点亮三色LED的红色灯。
- 2 时钟进入倒计时,时间到后,进入绿灯
- 现象为点亮三色LED的绿色灯,蜂鸣器进入鸣叫。
- 3 时钟进入倒计时,时间到后,进入黄灯(三色LED无黄灯,使用绿色和红色组合得到)
- 现象为点亮三色LED的黄色灯。
// LED控制逻辑
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
state <= RED;
timer <= 10;
main_cnt <= 0;
leds_reg <= 3'b011; // 红灯亮
end
else begin
main_cnt <= (main_cnt == 11_999_999) ? 0 : main_cnt + 1;
if(sec_pulse) begin
case(state)
RED: begin
if(timer > 0) timer <= timer - 1;
else begin
state <= GREEN; // 改为跳转至GREEN
timer <= 10; // 绿灯持续时间
leds_reg <= 3'b110; // 绿灯亮
end
end
GREEN: begin // YELLOW处理逻辑
if(timer > 0) timer <= timer - 1;
else begin
state <= YELLOW; // 改为跳转至YELLOW
timer <= 3; // 黄灯持续时间
leds_reg <= 3'b010; // 黄灯亮
end
end
YELLOW: begin // GREEN处理逻辑
if(timer > 0) timer <= timer - 1;
else begin
state <= RED;
timer <= 10;
leds_reg <= 3'b011; // 返回红灯
end
end
endcase
end
end
end
6.输出
- 数码管按照当前时序进行倒计时数值输出
- 蜂鸣器根据是否在绿灯鸣叫
- 三色LED按照当前时序进行颜色输出
// 数码管数据生成
always @(posedge clk) begin
num_hi <= (timer > 4'd9) ? (timer / 4'd10) : 4'd0;
num_lo <= (timer > 4'd9) ? (timer % 4'd10) : timer;
end
// 静态数码管输出
assign seg_hi = seg_table[num_hi];
assign seg_lo = seg_table[num_lo];
// 蜂鸣器输出逻辑
assign buzzer = (state == GREEN) ? (buzz_cnt < 1_500_000) : 0;
// LED输出
assign leds = leds_reg;
项目 二
完成任务 1.接近传感器检测人员走近 2.环境光感知,自动点亮路灯(小脚丫核心板上的单色LED)
项目设计框图
FPGA资源占用报告
1.模拟iic
环境光及接近传感器为iic传输接口,需使用FPGA模拟iic时序(具体代码请看项目文件)
rpr0521rs_driver u1(
.clk (clk ), //系统时钟
.rst_n (rst_n ), //系统复位,低有效
.i2c_scl (i2c_scl ), //I2C总线SCL
.i2c_sda (i2c_sda ), //I2C总线SDA
.dat_valid (dat_valid ), //数据有效脉冲
.ch0_dat (ch0_dat ), //ALS数据
.ch1_dat (ch1_dat ), //IR数据
.prox_dat (prox_dat ) //Prox数据
);
2.获取RPR-0521RS数据
模拟iic后,通过iic和环境光及接近传感器RPR-0521RS获取当前的环境光及接近
3.数据整理
对以获取数据进行整理、转换
4.输出
检测有人靠近点亮报警灯(核心板上的三色RGB灯)
当亮度低于500勒克斯点亮路灯(核心板单色LED)
通过底板数码管输出当前亮度
always@(posedge clk or negedge rst_n)//检测亮度大于一定值开路灯
if(rst_n == 1'b0)
led <= 8'b1111_1111;
else if(lux_data[31:08] < 500) //光照强度大于500开灯
led <= 8'b0000_0000;
else
led <= 8'b1111_1111;
always@(prox_dat2[11:9]) begin //检测有人靠进,点亮RGB灯
case (prox_dat2[11:9])
3'b000: Y_out = 3'b111;
3'b001: Y_out = 3'b111;
3'b010: Y_out = 3'b111;
3'b011: Y_out = 3'b111;
3'b100: Y_out = 3'b000;
3'b101: Y_out = 3'b000;
3'b110: Y_out = 3'b000;
3'b111: Y_out = 3'b000;
default:Y_out = 3'b111;
endcase
end
segment_scan u4(
.clk(clk), //系统时钟 12MHz
.rst_n(rst_n), //系统复位 低有效
.dat_1(lux_data[31:28] ), //SEG1 显示的数据输入
.dat_2(lux_data[27:24] ), //SEG2 显示的数据输入
.dat_3(lux_data[23:20] ), //SEG3 显示的数据输入
.dat_4(lux_data[19:16] ), //SEG4 显示的数据输入
.dat_5(lux_data[15:12] ), //SEG5 显示的数据输入
.dat_6(lux_data[11:08] ), //SEG6 显示的数据输入
.dat_7(lux_data[07:04] ), //SEG7 显示的数据输入
.dat_8(lux_data[03:00] ), //SEG8 显示的数据输入
.dat_en(8'b1111_1111 ), //数码管数据位显示使能,[MSB~LSB]=[SEG1~SEG8]
.dot_en(8'b0000_0100 ), //数码管小数点位显示使能,[MSB~LSB]=[SEG1~SEG8]
.seg_rck(seg_rck ), //74HC595的RCK管脚
.seg_sck(seg_sck ), //74HC595的SCK管脚
.seg_din(seg_din ) //74HC595的SER管脚
);//数码管亮度输出
四、功能展示图及说明
项目 一
状态:红灯 红灯点亮
状态:绿灯 绿灯点亮
状态:黄灯 黄灯点亮
项目 二
亮度低于500勒克斯,点亮路灯
亮度高于500勒克斯,模拟白天,路灯熄灭
检测人员靠近,点亮RGB三色灯
五、项目中遇到的难题和解决方法
困难:FPGA并行运行逻辑
因为日常学习为单片机,习惯了单片机的顺序执行逻辑,而这次是第一次接触FPGA,FPGA为并行运行,对于习惯顺序执行的我来说,是一个挑战,在编写代码过程中,经常出现并行逻辑冲突,导致代码跑飞。
解决途径:加强对FPGA的学习,对代码进行反复的实验。
六、对本次活动的心得体会
很高兴能参加这次活动,让我有机会参与FPGA的学习,同时感谢这次活动的时间充裕,能够让我对FPGA有一个更深入的了解,通过项目深入掌握了FPGA的硬件描述语言(Verilog)和状态机设计,提升了对传感器数据融合、多模块协同的理解。