赞
踩
本次设计目的为设计制作一个十字路口交通指示灯简易控制电路,该电路实现了红灯亮表示停止,绿灯亮表示通行,黄灯亮表示等待,通过控制数码管来显示时间,红绿灯通过控制LED灯来实现。
1、东西、南北两条路以绿灯20秒–黄灯4秒–红灯16秒的顺序,依次点亮LED灯。
2、采用倒计时显示剩余时间,每个路口使用两个七段数码管来显示剩余时间。
3、紧急情况下,可以通过按动紧急按钮,将东西、南北两方向的红绿灯都置为红灯。按动紧急按钮后,两方向都是红灯持续20秒,之后恢复正常亮灯顺序。
东西红–南北绿
东西红–南北黄
东西绿–南北红
南北红–东西黄
紧急情况:两边都是红灯
工程代码链接:
FPGA交通灯设计,基于vivado2018.3建立工程
工程代码也可以私信获取,本人工程基于vivado2018.3设计。
如有其他设计需求,可以联系扣扣:904259638,可接FPGA课设。
本题目主要需要设计的部分有三个,分别是:数码管控制部分,LED灯控制部分,以及紧急按钮按键控制部分。其中,数码管用来显示红绿灯剩余时间;LED灯用来显示当前是哪个方向红灯,哪个方向绿灯;紧急按钮用来控制紧急情况下红绿灯的显示。
整体逻辑框图如下:
其中,led_logic为交通灯逻辑控制模块,通过状态机来控制交通灯跳转。led_ctl为LED灯控制模块,通过交通灯led_logic模块的状态机来控制12个LED灯的亮灭。Usmg为数码管控制模块,通过led_logic输出的东西、南北方向的计数器,来控制四个方向的数码管显示。
各个模块代码如下:
顶层模块:
`timescale 1ns / 1ps
module jtd_test(
input clk,
input rst_n,
input key,
output [7:0] sm_bit,
output [7:0] sm_seg,
output [11:0] led
);
wire [4:0] c_state;
wire [4:0] time_second_cnt_dx;
wire [4:0] time_second_cnt_nb;
jtd_logic jtd_logic_inst(
.clk (clk),
.rst_n (rst_n),
.key (key),
.c_state (c_state),
.time_second_cnt_dx (time_second_cnt_dx), //东西方向数码管计数
.time_second_cnt_nb (time_second_cnt_nb)); //南北方向数码管计数
led_ctl led_ctl_inst(
.clk (clk),
.rst_n (rst_n),
.c_state (c_state),
.led (led));
wire [3:0] ge0;
wire [3:0] shi0;
wire [3:0] ge1;
wire [3:0] shi1;
wire [3:0] ge2;
wire [3:0] shi2;
wire [3:0] ge3;
wire [3:0] shi3;
assign ge1 = time_second_cnt_dx%10; //
assign shi1 = time_second_cnt_dx/10;
assign ge3 = time_second_cnt_dx%10;
assign shi3 = time_second_cnt_dx/10;
assign ge0 = time_second_cnt_nb%10;
assign shi0 = time_second_cnt_nb/10;
assign ge2 = time_second_cnt_nb%10;
assign shi2 = time_second_cnt_nb/10;
smg Usmg(
.clk (clk),
.rst_n (rst_n),
.shi3 (shi3),
.ge3 (ge3),
.shi2 (shi2),
.ge2 (ge2),
.shi1 (shi1),
.ge1 (ge1),
.shi0 (shi0),
.ge0 (ge0),
.sm_bit (sm_bit), //数码管选择输出引脚
.sm_seg (sm_seg) //数码管段输出引脚
);
endmodule
led控制模块
`timescale 1ns / 1ps
module led_ctl(
input clk,
input rst_n,
input [4:0] c_state,
output reg [11:0] led
);
parameter idle = 5'b00001,
stage_1 = 5'b00010,
stage_2 = 5'b00100,
stage_3 = 5'b01000,
emergent_led = 5'b10000;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
led <= 12'b0;
else if(c_state == idle)
led <= 12'b0111_1001_1110; //东西绿,南北红
else if(c_state == stage_1)
led <= 12'b0111_0101_1101; //南北红,东西黄
else if(c_state == stage_2)
led <= 12'b1100_1111_0011; //东西红,南北绿
else if(c_state == stage_3)
led <= 12'b1010_1110_1011; //东西红,南北黄
else if(c_state == emergent_led)
led <= 12'b0110_1101_1011; //东西红,南北红
else
led <= led;
end
endmodule
数码管模块:
`timescale 1ns / 1ps
module smg(
input clk,
input rst_n,
input [3:0] shi3,
input [3:0] ge3,
input [3:0] shi2,
input [3:0] ge2,
input [3:0] shi1,
input [3:0] ge1,
input [3:0] shi0,
input [3:0] ge0,
output reg [7:0] sm_bit, //数码管选择输出引脚
output reg [7:0] sm_seg //数码管段输出引脚
);
reg[3:0] disp_dat; //定义显示数据寄存器
reg[24:0]count; //定义计数寄存器
//秒信号产生部分
always @(posedge clk or negedge rst_n) //定义clock上升沿触发
begin
if(!rst_n)
count<=0;
//for sim
else if(count == 25'd250000)//if(count == 25'd25000000) //0.5S到了吗?
count = 25'd0; //计数器清零
else
count = count + 1'b1;
end
//数码管动态扫描显示部分
always @(posedge clk or negedge rst_n) //count[17:15]大约1ms改变一次
begin
if(!rst_n)
disp_dat<=0;
else
//case(count[17])//选择扫描显示数据
//for sim
case(count[15:13])//选择扫描显示数据
3'd0:disp_dat <= ge0 ;//第一个数码管个位
3'd1:disp_dat <= shi0 ;//第一个数码管十位
3'd2:disp_dat <= ge1 ;//第二个数码管个位
3'd3:disp_dat <= shi1 ;//第二个数码管十位
3'd4:disp_dat <= ge2 ;//第三个数码管个位
3'd5:disp_dat <= shi2 ;//第三个数码管十位
3'd6:disp_dat <= ge3 ;//第四个数码管个位
3'd7:disp_dat <= shi3 ;//第四个数码管十位
endcase
end
always @(posedge clk) //count[17:15]大约1ms改变一次
begin
//case(count[17]) //选择数码管显示位
//for sim
case(count[15:13]) //选择扫描显示数据
3'd0:sm_bit <= 8'b1111_1110;//选择第1个数码管显示
3'd1:sm_bit <= 8'b1111_1101;//选择第2个数码管显示
3'd2:sm_bit <= 8'b1111_1011;//选择第3个数码管显示
3'd3:sm_bit <= 8'b1111_0111;//选择第4个数码管显示
3'd4:sm_bit <= 8'b1110_1111;//选择第5个数码管显示
3'd5:sm_bit <= 8'b1101_1111;//选择第6个数码管显示
3'd6:sm_bit <= 8'b1011_1111;//选择第7个数码管显示
3'd7:sm_bit <= 8'b0111_1111;//选择第8个数码管显示
endcase
end
always @(posedge clk)
begin
case(disp_dat)
4'h0:sm_seg <= 8'hc0; //显示0
4'h1:sm_seg <= 8'hf9; //显示1
4'h2:sm_seg <= 8'ha4; //显示2
4'h3:sm_seg <= 8'hb0; //显示3
4'h4:sm_seg <= 8'h99; //显示4
4'h5:sm_seg <= 8'h92; //显示5
4'h6:sm_seg <= 8'h82; //显示6
4'h7:sm_seg <= 8'hf8; //显示7
4'h8:sm_seg <= 8'h80; //显示8
4'h9:sm_seg <= 8'h90; //显示9
4'ha:sm_seg <= 8'hbf; //显示-
default:sm_seg <= 8'hff; //不显示
endcase
end
endmodule
交通灯逻辑控制模块:
`timescale 1ns / 1ps
module jtd_logic(
input clk,
input rst_n,
input key,
output reg [4:0] c_state,
output reg [4:0] time_second_cnt_dx,
output reg [4:0] time_second_cnt_nb
);
parameter time_1s=5000_000_0;
parameter idle = 5'b00001,
stage_1 = 5'b00010,
stage_2 = 5'b00100,
stage_3 = 5'b01000,
emergent_led = 5'b10000;
reg key_reg; //按键寄存,为了后续识别按键上升沿
wire key_flag; //按键标志,拉高证明按键被按动;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
key_reg <= 1'b1;
else
key_reg <= key;
end
assign key_flag = ((!key)&&(key_reg))?1'b1:1'b0; //按键识别到下降沿,证明按键了
reg [4:0] n_state;
reg [31:0] cnt;
reg east_west_green_end;
reg east_west_yellow_end;
reg south_north_green_end;
reg south_north_yellow_end;
reg emergent_end;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt<=0;
else if(cnt==time_1s-1)
cnt<=0;
else
cnt<=cnt+1;
end
reg [5:0] time_cnt;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
time_cnt <= 'd15;
else if(cnt==time_1s-1)
time_cnt <= time_cnt - 'd1;
else
time_cnt <= time_cnt;
end
//***************************状态机***********************//
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
c_state <= idle;
else
c_state <= n_state;
end
//东西方向:east_west 南北方向:south_north
always@(*)
begin
n_state = c_state;
case(n_state)
idle: //南北红16秒,东西绿16秒,东西绿结束标志到来,开始黄灯
begin
if(key_flag)
n_state = emergent_led;
else if(east_west_green_end)
n_state = stage_1;
else
n_state = idle;
end
stage_1: //东西黄灯4秒,南北继续红灯4秒,东西黄结束标志到来,东西开始红灯,南北变绿灯;
begin
if(key_flag)
n_state = emergent_led;
else if(east_west_yellow_end)
n_state = stage_2;
else
n_state = stage_1;
end
stage_2://东西红灯16秒,南北绿灯16秒,南北绿结束标志到来,南北开始黄灯
begin
if(key_flag)
n_state = emergent_led;
else if(south_north_green_end)
n_state = stage_3;
else
n_state = stage_2;
end
stage_3://南北黄灯4秒,东西继续红灯4秒,南北黄结束标志到来,南北开始红灯,东西变绿灯。
begin
if(key_flag)
n_state = emergent_led;
else if(south_north_yellow_end)
n_state = idle;
else
n_state = stage_3;
end
emergent_led: //紧急情况,按键被按下后,东西南北四个方向都亮红灯20秒
if(emergent_end)
n_state = idle;
else
n_state = emergent_led;
default:
n_state = idle;
endcase
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
emergent_end <= 'd0;
else if(time_second_cnt_dx == 'd0 && c_state == emergent_led)
emergent_end <= 'd1;
else if(c_state == emergent_led && n_state == idle)
emergent_end <= 'd0;
else
emergent_end <= emergent_end;
end
reg [4:0] time_second_cnt_dx; //东西方向数码管计数
reg [4:0] time_second_cnt_nb; //南北方向数码管计数
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
time_second_cnt_dx <= 'd16;
time_second_cnt_nb <= 'd20; //南北红20秒,东西绿16秒
end
else if((c_state == idle && n_state == emergent_led)||
(c_state == stage_1 && n_state == emergent_led)||
(c_state == stage_2 && n_state == emergent_led)||
(c_state == stage_3 && n_state == emergent_led))begin
time_second_cnt_dx <= 'd20;
time_second_cnt_nb <= 'd20;
end
else if(c_state == idle)begin
if(time_second_cnt_dx == 'd0)
time_second_cnt_dx <= 'd4;
else if(cnt==time_1s-1)begin
time_second_cnt_dx <= time_second_cnt_dx - 'd1;
time_second_cnt_nb <= time_second_cnt_nb - 'd1;
end
else begin
time_second_cnt_dx <= time_second_cnt_dx;
time_second_cnt_nb <= time_second_cnt_nb;
end
end
else if(c_state == stage_1)begin
if(time_second_cnt_dx == 'd0)begin
time_second_cnt_dx <= 'd20;
time_second_cnt_nb <= 'd16;
end
else if(cnt==time_1s-1)begin
time_second_cnt_dx <= time_second_cnt_dx - 'd1;
time_second_cnt_nb <= time_second_cnt_nb - 'd1;
end
else begin
time_second_cnt_dx <= time_second_cnt_dx;
time_second_cnt_nb <= time_second_cnt_nb;
end
end
else if(c_state == stage_2)begin
if(time_second_cnt_nb == 'd0)
time_second_cnt_nb <= 'd4;
else if(cnt==time_1s-1)begin
time_second_cnt_dx <= time_second_cnt_dx - 'd1;
time_second_cnt_nb <= time_second_cnt_nb - 'd1;
end
else begin
time_second_cnt_dx <= time_second_cnt_dx;
time_second_cnt_nb <= time_second_cnt_nb;
end
end
else if(c_state == stage_3)begin
if(time_second_cnt_dx == 'd0)begin
time_second_cnt_nb <= 'd20;
time_second_cnt_dx <= 'd16;
end
else if(cnt==time_1s-1)begin
time_second_cnt_dx <= time_second_cnt_dx - 'd1;
time_second_cnt_nb <= time_second_cnt_nb - 'd1;
end
else begin
time_second_cnt_dx <= time_second_cnt_dx;
time_second_cnt_nb <= time_second_cnt_nb;
end
end
else if(c_state == emergent_led)begin
if(time_second_cnt_dx == 'd0)begin
time_second_cnt_dx <= 'd16;
time_second_cnt_nb <= 'd20;
end
else if(cnt == time_1s-1)begin
time_second_cnt_dx <= time_second_cnt_dx - 'd1;
time_second_cnt_nb <= time_second_cnt_nb - 'd1;
end
else begin
time_second_cnt_dx <= time_second_cnt_dx;
time_second_cnt_nb <= time_second_cnt_nb;
end
end
else begin
time_second_cnt_dx <= time_second_cnt_dx;
time_second_cnt_nb <= time_second_cnt_nb;
end
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
east_west_green_end <= 'd0;
east_west_yellow_end <= 'd0;
south_north_green_end <= 'd0;
south_north_yellow_end <= 'd0;
end
else if(c_state == idle && time_second_cnt_dx == 'd0)begin
east_west_green_end <= 'd1;
east_west_yellow_end <= 'd0;
south_north_green_end <= 'd0;
south_north_yellow_end <= 'd0;
end
else if(c_state == stage_1 && time_second_cnt_nb == 'd0)begin
east_west_green_end <= 'd0;
east_west_yellow_end <= 'd1;
south_north_green_end <= 'd0;
south_north_yellow_end <= 'd0;
end
else if(c_state == stage_2 && time_second_cnt_nb == 'd0)begin
east_west_green_end <= 'd0;
east_west_yellow_end <= 'd0;
south_north_green_end <= 'd1;
south_north_yellow_end <= 'd0;
end
else if(c_state == stage_3 && time_second_cnt_dx == 'd0)begin
east_west_green_end <= 'd0;
east_west_yellow_end <= 'd0;
south_north_green_end <= 'd0;
south_north_yellow_end <= 'd1;
end
else begin
east_west_green_end <= 'd0;
east_west_yellow_end <= 'd0;
south_north_green_end <= 'd0;
south_north_yellow_end <= 'd0;
end
end
endmodule
附上管脚分配:
set_property PACKAGE_PIN Y18 [get_ports clk]
set_property PACKAGE_PIN F15 [get_ports rst_n]
set_property PACKAGE_PIN G18 [get_ports led[11]]
set_property PACKAGE_PIN R17 [get_ports led[10]]
set_property PACKAGE_PIN H15 [get_ports led[9]]
set_property PACKAGE_PIN P17 [get_ports led[8]]
set_property PACKAGE_PIN AB22 [get_ports led[7]]
set_property PACKAGE_PIN T18 [get_ports led[6]]
set_property PACKAGE_PIN U18 [get_ports led[5]]
set_property PACKAGE_PIN W17 [get_ports led[4]]
set_property PACKAGE_PIN AB18 [get_ports led[3]]
set_property PACKAGE_PIN R14 [get_ports led[2]]
set_property PACKAGE_PIN N14 [get_ports led[1]]
set_property PACKAGE_PIN R16 [get_ports led[0]]
set_property PACKAGE_PIN J15 [get_ports sm_bit[0]]
set_property PACKAGE_PIN G17 [get_ports sm_bit[1]]
set_property PACKAGE_PIN R18 [get_ports sm_bit[2]]
set_property PACKAGE_PIN N17 [get_ports sm_bit[3]]
set_property PACKAGE_PIN AA18 [get_ports sm_bit[4]]
set_property PACKAGE_PIN U17 [get_ports sm_bit[5]]
set_property PACKAGE_PIN P15 [get_ports sm_bit[6]]
set_property PACKAGE_PIN P14 [get_ports sm_bit[7]]
set_property PACKAGE_PIN N4 [get_ports sm_seg[0]]
set_property PACKAGE_PIN N3 [get_ports sm_seg[1]]
set_property PACKAGE_PIN P2 [get_ports sm_seg[2]]
set_property PACKAGE_PIN N2 [get_ports sm_seg[3]]
set_property PACKAGE_PIN P6 [get_ports sm_seg[4]]
set_property PACKAGE_PIN N5 [get_ports sm_seg[5]]
set_property PACKAGE_PIN M6 [get_ports sm_seg[6]]
set_property PACKAGE_PIN M5 [get_ports sm_seg[7]]
set_property PACKAGE_PIN A20 [get_ports key]
set_property IOSTANDARD LVCMOS33 [get_ports key]
set_property IOSTANDARD LVCMOS33 [get_ports led[11]]
set_property IOSTANDARD LVCMOS33 [get_ports led[10]]
set_property IOSTANDARD LVCMOS33 [get_ports led[9]]
set_property IOSTANDARD LVCMOS33 [get_ports led[8]]
set_property IOSTANDARD LVCMOS33 [get_ports led[7]]
set_property IOSTANDARD LVCMOS33 [get_ports led[6]]
set_property IOSTANDARD LVCMOS33 [get_ports led[5]]
set_property IOSTANDARD LVCMOS33 [get_ports led[4]]
set_property IOSTANDARD LVCMOS33 [get_ports led[3]]
set_property IOSTANDARD LVCMOS33 [get_ports led[2]]
set_property IOSTANDARD LVCMOS33 [get_ports led[1]]
set_property IOSTANDARD LVCMOS33 [get_ports led[0]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_bit[0]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_bit[1]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_bit[2]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_bit[3]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_bit[4]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_bit[5]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_bit[6]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_bit[7]]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports sm_seg[0]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_seg[1]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_seg[2]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_seg[3]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_seg[4]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_seg[5]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_seg[6]]
set_property IOSTANDARD LVCMOS33 [get_ports sm_seg[7]]
注意:由于芯片办卡不同,管脚分配也不会相同,本人使用的开发板用的芯片为Xilinx A735t,且交通灯为外设模块,管脚分配不一定和大家的一样。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。