2025寒假练 - 基于小脚丫FPGA平台的交通灯控制系统设计
该项目使用了小脚丫FPGA STEP BaseBoard V4.0套件,实现了交通灯控制系统的设计,它的主要功能为:交通灯计时、行人检测、光照检测亮灯和报警控制,主要的硬件为数码管,74HC595, 按键,蜂鸣器,环境光和接近传感器和LED灯。
标签
嵌入式系统
FPGA
交通灯
参加活动/培训
硬禾活动作业
张一西
更新2025-03-17
286

1、项目概况

本设计旨在利用小脚丫FPGA STEP BaseBoard V4.0开发板构建一个模拟交通控制系统,主要的需求如下:

  • 在数码管上显示计时信息
  • 蜂鸣器报警
  • 接近传感器检测人员走近
  • 环境光感知,自动点亮路灯

根据以上需求,可以细化上述需求,主要的交通控制系统功能如下:

  • 基本的交通灯倒计时功能,倒计时结束后切换成对应的灯光,例如红灯之后绿灯,绿灯之后黄灯
  • 黄灯时,蜂鸣器报警,也可以通过按键控制其不报警
  • 接近传感器的数值可以在数码管显示,接近人员时,自动蜂鸣器报警,也可以控制其不报警
  • 根据环境光照强度自动亮LED灯光,光照越弱,灯光越强,模拟路灯,同时数码管显示光照强度
  • 光照强度和接近传感器的数值通过按键可以进行切换显示

主要使用的FPGA平台如下:

FheM1anVmLBxLX0YIiIxNkkAIWf6

2、项目总体方案框图

项目总体框图如下:

交通灯控制系统框图.png

FPGA的顶层文件设计如下:

交通灯顶层文件框图.png

根据细化的需求,拆分相关的模块如下:

  • multi_color:根据选择输入的选择,点亮对应的灯光,项目中主要是红灯、绿灯和黄灯,两个三色灯可以单独控制,也可以组合其他其他颜色,改变输入的选择即可
  • segment_led:根据输入的数据,显示对应的数码管,这里数码管为核心板数码管
  • div:分频器,系统频率生成1KHZ
  • counter:主要根据输入的1KHZ频率,生成对应的交通灯计时
  • prox_detect:使用IIC总线读取光照和接近传感器数据
  • decoder:对IIC读取的数据进行处理和判断,点亮对应的单色LED灯
  • beeper:根据控制输入,驱动蜂鸣器报警
  • bin_to_lcd:将数据转成BCD码
  • segment_scan:利用74hc595 串转并显示对应的数据,为底板数码管驱动显示


FPGA的输入输出流向图如下图所示。

FPGA流向图.png

3、硬件使用介绍

使用到的硬件主要有如下:

  • 数码管:IO驱动数码管和74hc595串转并驱动数码管
  • 74HC595:串转并驱动芯片
  • 按键:拨码以及点击按键
  • 蜂鸣器:无源蜂鸣器,需要输入特定频率驱动
  • 环境光和接近传感器:IIC协议总线,集光照传感器和接近传感器于一体
  • LED灯:单色和三色LED灯


2个74HC595 来控制8个数码管,主要使用三个管脚,SERSRCLK,RCLK,时钟频率为40KHZ

  • SER:串行数据输入管脚,数据从SER口排着队依次进入。
  • SRCLK:移位寄存器的时钟输入
    • 数据从SER口排着队等待进入,该管脚输入低电平,则SER接收一位数据。
  • RCLK:存储计时器时钟的输入引脚
    • 把SER输入的8位数据存储起来,输入高电平,把移位寄存器中的8位数据一次性转存到存储时钟当中。


实验中有8个数码管,则需要2个74HC595芯片控制,一个控制数码管的位置,一个控制数码管的数据。

  • 首先初始化管脚状态
  • 其次把控制的数码管位置以及数码管封住成整体数据,1个16位数据
  • 接着通过sclk时钟,逐位通过SER管脚输出,则点亮单个数码管
  • 最后扫描8个数码管,通过状态机逐个数码管显示对应数据

具体电路与时序图如下

image.png

image.png

RPR-0521光照和接近传感器:使用IIC总线通信,400KHZ频率,通过读取固寄存器地址,可以分多次将数据读出。寄存器列表如下:

image.png

  • 首先写0x40 地址,初始化传感器,主要是复位
  • 其次写0x41地址,使能光照和接近传感器,0x42和43配置两个传感器增益数值
  • 接着就通过0x44、0x45读取接近传感器数值,12位数值
  • 然后通过0x46/47/48/48读出光照传感器,32位数值

image.png

4、功能模块设计与展示

4.1、交通灯倒计时

交通灯倒计时.png

核心verilog代码如下:

always @ (posedge clk_1hz or negedge rst_n) begin
if(!rst_n)
begin
counter_high <= 4'd1;
counter_low <= 4'd9;
sel_type <= 2'd1;
end
else if(counter_high <= 4'd0 && counter_low <= 4'd0)
begin
case(sel_type)
2'd1: begin counter_high <= 4'd0;counter_low <= 4'd9;end
2'd2: begin counter_high <= 4'd0;counter_low <= 4'd3;end
2'd3: begin counter_high <= 4'd1;counter_low <= 4'd9;end
default: begin counter_high <= 4'd1;counter_low <= 4'd9;end
endcase
if(sel_type >= 2'd3)
sel_type <= 1'd1;
else
sel_type <= sel_type + 1'd1;
end
else if(counter_low <= 4'd0)
begin
counter_low <= 4'd9;
counter_high <= counter_high - 4'd1;
end
else
counter_low <= counter_low - 4'd1;
end
  • 主要采用的是状态机进行红灯、绿灯和黄灯的切换,状态值为sel_type,交通灯时间由对应的状态初始赋值指定,然后进行对应时间的倒计时,
  • 倒计时时间通过高低位两个counter记录,分别显示在对应的数码管上面。
  • 复位按键之后,会初始化成红灯状态,倒计时也赋值成初始值
  • 根绝sel_type状态,可以设置对应的行为,比如蜂鸣器报警等等


4.2、接近传感器检测行人与光照检测自动亮路灯

传感器检测.png

距离检测与报警核心逻辑Verilog:

always @(posedge dat_valid) begin
prox_dat0 <= prox_dat;
prox_dat1 <= prox_dat0;
if(((prox_dat1-prox_dat0) >= 16'h800)||((prox_dat1-prox_dat0) >= 16'h800))
prox_dat2 <= prox_dat2;
else
prox_dat2 <= prox_dat0;
if(prox_dat2 > 8'd150)
beeper_sel = 1'b1;
else
beeper_sel = 1'b0;

end
  • prox_dat1 与prox_dat0用来记录前后的两个距离值,可以用来过滤坏值,如果两次差距较大,则保留前一次值
  • 最终Prox_dat2是最终的输出值,其值大小可以检测判断,比如蜂鸣器的报警信号


距离数据与光照数据核心逻辑Verilog:

always@(data0 or data1) begin
if(show_type)
begin
if(data1 < data0*595)
lux = data0*1682 - data1*1877;
else if(data1 < data0*1015)
lux = data0*644 - data1* 132;
else if(data1 < data0*1352)
lux = data0*756 - data1*243;
else if((data1 < data0*3053))
lux = data0*766 - data1*25;
else
lux = 0;
end
else
begin
lux = {16'b0,prox_dat2};
end
end
  • 前面用来计算光照单位数据lux,后面用来保存距离数据
  • 通过show_type,用于显示光照数据还是距离数据

根据光照强度LED灯光的核心Verilog如下图所示:

always@(lux_back) begin
if(lux_back > 7000)
Y_out = 8'b11111111;
else if(lux_back > 6000)
Y_out = 8'b11111110;
else if(lux_back > 5000)
Y_out = 8'b11111100;
else if(lux_back > 4000)
Y_out = 8'b11111000;
else if(lux_back > 3000)
Y_out = 8'b11110000;
else if(lux_back > 2000)
Y_out = 8'b11100000;
else if(lux_back > 1000)
Y_out = 8'b11000000;
else if(lux_back > 500)
Y_out = 8'b10000000;
else
Y_out = 8'b00000000;
end
  • 根据光照强度,由高到低,逐步点亮更多的LED灯,光照越强,LED越少;光照越弱,LED灯越多。

4.3、蜂鸣器报警系统

蜂鸣器报警系统.png

核心报警verilog代码如下:

always @(posedge beeper_clk)
begin
if(sw_beeper_sel)
begin
if(beeper_en == 2'd3)
begin
if(beeper_counter >= 2)
beeper <= 1'b0;
else
beeper <= 1'b1;
end
else
beeper <= 1'b0;
end
else
begin
if(beeper_sel == 1'd1)
begin
if(beeper_counter >= 2)
beeper <= 1'b0;
else
beeper <= 1'b1;
end
else
beeper <= 1'b0;
end
end
  • 根据输入的时钟,生成蜂鸣器需要的时钟频率和相位,250HZ,占空比50%
  • 根据按键控制sw_beeper_sel,选择对应的事件蜂鸣器报警,主要是两个事件,黄灯事件和行人检测事件

5、项目FPGA资源使用

项目硬件展示如下图所示:(任务一二三四均在一个工程完成)

41063cee878f11fddfdad2429f308ea.jpg

项目使用到的FPGA资源如下图所示:


image.png

Web IDE项目连接为:https://www.stepfpga.com/project/17252/gui?type=top

其使用的资源如下图所述:

image.png

6、项目总结与展望

6.1、项目总结与展望

  • 交通灯整体功能逻辑相当简单,主要是传感器 IIC的驱动,不过也可以参考例程,做简单的修改,即可完成任务。
  • 后续计划上位机完成一个交通灯的计时控制,然后通过uart下发到FPGA平台显示,通过下发指令控制,可以使得FPGA平台显示对应的时间,状态等等
  • 也可以通过uart下发交通灯计时图片,然后到LCD屏幕进行显示。


6.2 、心得与感受

  • 小脚丫FPGA平台底板外设丰富,用例也比较丰富,开发起来相当方便,例如通用的uart协议、IIC协议以及SPI协议等等,都有一些例程来使用和驱动外设,很适合新手入门和进阶者,小脚丫FPGA4000多个逻辑门,对于一般的项目也可以用来做前期的验证,比较推荐
  • 支持Lattice IDE开发和Web IDE开发双开发方式,摆脱了对于传统IDE的强烈依赖,同时Web IDE整体使用下来,并没有群里说的那样难用,基本verilog开发好之后,一晚上就搞定了图形化开发,还是相当方便的,
    • 一个建议就是模块使用ctrl+s保存的时候,似乎会把顶层设计文件保存到模块,然后顶层文件就丢失了,回不去了。
    • 还有就是Web IDE仿真有时只是显示编译结果,不显示仿真波形,或者全黑,不知道什么情况

7、参考

附件下载
traffic_control_led.zip
所有文件打包,内含readme说明
traffic_control_led_Lattice_download_jed_file.jed
为Lattice Diamond 编译出的下载文件,集任务一二三四于一体
traffic_control_led_Lattice_project.zip
为Lattice Diamond 工程,可编译出traffic_control_led_Lattice_download_jed_file
traffic_control_led_WebIDE_download_jed_file.jed
Web IDE图形化编译出的下载文件,针对任务一和二
traffic_control_led_WebIDE_project.zip
为 WebIDE图形化的工程文件,里面包含图形化对应的Verilog 文件和下载文件
团队介绍
一名嵌入式工程师,励志做自己喜欢的玩具,喜欢研究芯片底层架构,编程模型,指令集等,热爱去研究使用开源软件,跑步、乒乓球爱好者,个人网站一西站点:http://zyixi.xyz/
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号