2025寒假练-基于小脚丫FPGA实现交通灯控制系统
该项目使用了基于Lattice MXO2的小脚丫FPGA核心板,实现了交通灯控制系统的设计,它的主要功能为:在数码管上显示计时信息、蜂鸣器报警、接近检测和环境光感知。。
标签
FPGA
开发板
参加活动/培训
lbbxy
更新2025-03-19
北京理工大学
17

项目介绍

使用WebIDE的图形化编程,使用常规的74系列的元器件,构建一个交通灯控制系统:

要求1:在数码管上显示计时信息- 图形化

要求2:蜂鸣器报警- 图形化

要求3:接近传感器检测人员走近-Verilog

要求4:环境光感知,自动点亮路灯(小脚丫核心板上的单色LED)- Verilog

使用板卡:STEP Baseboard4.0底板+STEP MXO2 LPC核心板

前两个要求用WebIDE的图形化实现,后两个要求用本地软件Diamond来实现。 

 

设计思路

由于要求1与要求2通过同一个工程得到实现,要求3与要求4通过另一个工程实现,所以在后续的报告中将分开介绍两者。

要求1与要求2

1.系统功能概述

根据项目需求进行分析,所设计的交通灯控制系统应具备以下几个核心功能: 

  • 整数分频器将高频的系统时钟分频为低频信号,以驱动状态机和倒计时逻辑。
  • 通过状态机控制交通灯的四种状态(S1-S4),每个状态对应不同的LED灯组合和倒计时时间以及蜂鸣器报警信号。
  • 核心板上的数码管实时显示倒计时数值,三色LED灯实时变换颜色,蜂鸣器在状态切换时发出警报。

2.模块划分

为了实现核心功能,并适应图形化编程的特点,将系统划分为五个模块:

  • 主模块:顶层模块,连接所有子模块,协调时钟、复位、蜂鸣器、数码管和交通灯等信号的传输。
  • 时钟分频模块:将系统时钟分频为低频信号,供状态机使用。
  • 状态机与倒计时模块:实现状态机逻辑,管理倒计时、LED状态切换和蜂鸣信号。
  • 蜂鸣器模块:根据状态机的标志信号生成特定频率的蜂鸣警报。
  • 数码管显示模块:将倒计时数值转换为七段数码管编码并输出。

模块划分图

3.流程图

本系统采用的状态机包含状态S1、S2、S3、S4,通过倒计时结束来触发状态切换,形成闭环。状态机切换的流程图如下:


流程图

要求3与要求4

要求3和要求4可以通过修改平台所给的lab8例程来实现。分析可得,原有的例程可实现的功能是:在数码管上实时显示光照强度、通过核心板上亮起的单色LED灯的个数体现事物与接近传感器的距离。因此,只需要在此基础上进行修改以实现这两个功能:

  • 接近传感器检测:当人员或物体靠近接近传感器时,点亮一个单色LED灯。
  • 环境光感知:当环境光减弱到一定程度时,点亮一个单色LED灯。

根据要求,整个系统的框图设计为:


细节上,人员走近检测和自动感应路灯是两个独立的功能,它们的流程图如下:

 

关键代码介绍

要求1与要求2

前两个要求是通过WebIDE的图形化编程实现的,项目链接为:程序WebIDE链接

根据上一步的设计,框架主体包括时钟分频模块、状态机与倒计时模块、蜂鸣器控制模块与数码管显示模块。

时钟分频模块

分频器根据分频系数(参数N)生成低频时钟信号,输出一个1秒的时钟周期clk1h。

assign clkout = (N==1)? clk1:(N[0]? clk3:clk2);	

状态机与倒计时模块

1. 状态机设计

定义了四个状态:S1对应的是红灯,倒计时为9秒;S2对应的是红蓝灯,倒计时为3秒;S3对应的是绿灯,倒计时为7秒;S4对应的是白灯,倒计时为3秒。

parameter      	S1 = 4'b00,    //状态机状态编码
S2 = 4'b01,
S3 = 4'b10,
S4 = 4'b11;

parameter time_s1 = 4'd9, //计时参数
time_s2 = 4'd3,
time_s3 = 4'd7,
time_s4 = 4'd3;

//交通灯的控制
parameter led_s1 = 6'b110110, // 红色
led_s2 = 6'b011110, // 红蓝色
led_s3 = 6'b101101, // 绿色
led_s4 = 6'b000000; // 白色

2. 第一段(同步逻辑)

描述次态到现态的转移,根据复位信号或时钟更新当前状态。

always @ (posedge clk1h or negedge rst_n)
begin
if(!rst_n)
cur_state <= S1;
else
cur_state <= next_state;
end

3. 第二段(组合逻辑)

状态切换逻辑。通过判断倒计时(tiomecont)是否归零来切换状态,并更新倒计时数值以及蜂鸣信号。

always @ (cur_state or rst_n or timecont)
begin
if(!rst_n) begin
next_state = S1;
end
else begin
case(cur_state)
S1:begin
if(timecont==1) begin
next_state = S2;
flag=1'b0;end
else begin
next_state = S1;
flag=1'b0;end
end

S2:begin
if(timecont==1) begin
next_state = S3;
flag=1'b1;end
else begin
next_state = S2;
flag=1'b1;end
end

S3:begin
if(timecont==1) begin
next_state = S4;
flag=1'b0;end
else begin
next_state = S3;
flag=1'b0;end
end

S4:begin
if(timecont==1) begin
next_state = S1;
flag=1'b1;end
else begin
next_state = S4;
flag=1'b1;end
end

default: next_state = S1;
endcase
end
end

4. 第三段(同步逻辑)

倒计时与输出控制。根据系统当前所处状态来更新倒计时和数码管显示数值,LED灯的输出也在这个部分实现。

always @ (posedge clk1h or negedge rst_n)
begin
if(!rst_n==1) begin
out <= led_s1;
timecont <= time_s1;
cnt_ge <= 4'd9;
end
else begin
case(next_state)
S1:begin
out <= led_s1;
if(timecont == 1) begin
timecont <= time_s1;
cnt_ge <= 4'd9;end
else begin
timecont <= timecont - 1;
cnt_ge <= cnt_ge - 1;end
end

S2:begin
out <= led_s2;

if(timecont == 1) begin
timecont <= time_s2;
cnt_ge <= 4'd3;end
else begin
timecont <= timecont - 1;
cnt_ge <= cnt_ge - 1;
end
end

S3:begin
out <= led_s3;
if(timecont == 1) begin
timecont <= time_s3;
cnt_ge <= 4'd7;end
else begin
timecont <= timecont - 1;
cnt_ge <= cnt_ge - 1;end
end

S4:begin
out <= led_s4;
if(timecont == 1) begin
timecont <= time_s4;
cnt_ge <= 4'd3;end
else begin
timecont <= timecont - 1;
cnt_ge <= cnt_ge - 1;end
end

default:begin
out <= led_s1;
end
endcase
end
end

蜂鸣器控制模块

由于板卡内置的蜂鸣器是一个无源蜂鸣器,所以需要生成方波信号来使它蜂鸣报警。使用计数器生成指定频率的方波信号,只有当蜂鸣信号(flag)有效时,计数器才会翻转beep信号,生成方波,蜂鸣器发出警报声。

 reg beep;
reg [31:0] counter;// 计数器

parameter CLK_FREQ = 50000000;// 输入时钟频率
parameter BEEP_FREQ = 2000;//蜂鸣器频率
localparam HALF_PERIOD = CLK_FREQ / (2* BEEP_FREQ);

//生成固定频率方波
always @ (posedge clk or negedge rst_n)begin
if(!rst_n)begin
counter <= 0;
beep <= 0;end
else if (flag)begin
if(counter >= HALF_PERIOD -1)begin
counter <= 0 ;
beep <= ~beep ;end//翻转信号
else begin
counter <= counter + 1 ;end
end
end

数码管显示模块

先把十进制数值转换为七段数码管编码。

 reg   		[6:0]   seg		[9:0];

//数显设置
initial
begin
seg[0] = 7'h3f; // 0
seg[1] = 7'h06; // 1
seg[2] = 7'h5b; // 2
seg[3] = 7'h4f; // 3
seg[4] = 7'h66; // 4
seg[5] = 7'h6d; // 5
seg[6] = 7'h7d; // 6
seg[7] = 7'h07; // 7
seg[8] = 7'h7f; // 8
seg[9] = 7'h6f; // 9
end

将倒计时的个位数值和十位数值分别映射到两个数码管。

assign seg_led_1[8:0] = {2'b00,seg[cnt_ge]};
assign seg_led_2[8:0] = {2'b00,seg[cnt_shi]};

管脚分配

程序的管脚分配如下:

 

要求3与要求4

程序代码是在所给例程上进行修改得到的,与原有例程对比,删去了整个segment.v文件以及decoder.v和prox_detect.v文件里有关数码管显示的部分。

在decoder.v增加以下关键模块,初始态没有LED小灯亮起,当感应到人员靠近接近传感器时,核心板上的第一个单色LED小灯亮起;当感应到环境光减弱到一定程度时,核心板上的最后一个单色LED小灯亮起。

// LED控制
always @(*) begin
Y_out = 8'b11111111;
// 接近检测
if(prox_dat2 > 16'h200)
Y_out[0]= 1'b0;
// 环境光感知
if(lux_data[31:08]<5'b11110 )
Y_out[7]= 1'b0;
end

功能展示图及说明

要求1与要求2

程序开始运行,首先显示红灯倒计时。

 

红灯结束后,变为红蓝灯并发出蜂鸣,持续3秒。

 

显示绿灯倒计时,时长为7秒。

 

绿灯结束后,变为白灯并发出蜂鸣,持续3秒。之后将继续显示红灯,进行循环。

 

要求3与要求4

初始没有小灯亮起。

 

当笔头靠近接近传感器时,第一个小灯亮起。

 

当环境光变弱时,最后一个小灯亮起。

 

用手覆盖住两个传感器所在的位置,两个小灯都亮起。

 

FPGA资源占用报告

要求1与要求2

Design Summary:
Number of registers: 82 out of 4635 (2%)
PFU registers: 82 out of 4320 (2%)
PIO registers: 0 out of 315 (0%)
Number of SLICEs: 85 out of 2160 (4%)
SLICEs as Logic/ROM: 85 out of 2160 (4%)
SLICEs as RAM: 0 out of 1620 (0%)
SLICEs as Carry: 63 out of 2160 (3%)
Number of LUT4s: 169 out of 4320 (4%)
Number used as logic LUTs: 43
Number used as distributed RAM: 0
Number used as ripple logic: 126
Number used as shift registers: 0
Number of PIO sites used: 27 + 4(JTAG) out of 105 (30%)
Number of block RAMs: 0 out of 10 (0%)
Number of GSRs: 1 out of 1 (100%)
EFB used : No
JTAG used : No
Readback used : No
Oscillator used : No
Startup used : No
POR : On
Bandgap : On
Number of Power Controller: 0 out of 1 (0%)
Number of Dynamic Bank Controller (BCINRD): 0 out of 6 (0%)
Number of Dynamic Bank Controller (BCLVDSO): 0 out of 1 (0%)
Number of DCCA: 0 out of 8 (0%)
Number of DCMA: 0 out of 2 (0%)
Number of PLLs: 0 out of 2 (0%)
Number of DQSDLLs: 0 out of 2 (0%)
Number of CLKDIVC: 0 out of 4 (0%)
Number of ECLKSYNCA: 0 out of 4 (0%)
Number of ECLKBRIDGECS: 0 out of 2 (0%)

要求3与要求4

 Design Summary
Number of registers: 214 out of 4635 (5%)
PFU registers: 212 out of 4320 (5%)
PIO registers: 2 out of 315 (1%)
Number of SLICEs: 972 out of 2160 (45%)
SLICEs as Logic/ROM: 972 out of 2160 (45%)
SLICEs as RAM: 0 out of 1620 (0%)
SLICEs as Carry: 342 out of 2160 (16%)
Number of LUT4s: 1943 out of 4320 (45%)
Number used as logic LUTs: 1259
Number used as distributed RAM: 0
Number used as ripple logic: 684
Number used as shift registers: 0
Number of PIO sites used: 15 + 4(JTAG) out of 105 (18%)
Number of block RAMs: 0 out of 10 (0%)
Number of GSRs: 1 out of 1 (100%)
EFB used : No
JTAG used : No
Readback used : No
Oscillator used : No
Startup used : No
POR : On
Bandgap : On
Number of Power Controller: 0 out of 1 (0%)
Number of Dynamic Bank Controller (BCINRD): 0 out of 6 (0%)
Number of Dynamic Bank Controller (BCLVDSO): 0 out of 1 (0%)
Number of DCCA: 0 out of 8 (0%)
Number of DCMA: 0 out of 2 (0%)
Number of PLLs: 0 out of 2 (0%)
Number of DQSDLLs: 0 out of 2 (0%)
Number of CLKDIVC: 0 out of 4 (0%)
Number of ECLKSYNCA: 0 out of 4 (0%)
Number of ECLKBRIDGECS: 0 out of 2 (0%)

难题和解决方法

在刚开始尝试实现第二个任务要求的时候,发现蜂鸣器总是不工作,后来经过学习才发现无源蜂鸣器需要靠方波信号激发。

 心得体会

通过这次实践第一次接触到FPGA,尽管过程中出现了很多问题,但在最后功能得到实现的那一刻是很有成就感的,体会到了程序开发的乐趣。同时,通过这次活动提升了自己的编程能力和动手能力。

附件下载
archive.zip
lab8_prox_detect.zip
团队介绍
北京理工大学 刘雪妍
团队成员
lbbxy
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号