摘要
交通灯控制器在城市交通监管中起着极其重要的作用。传统的交通灯控制器基本是通过单片机或者PLC实现的。本文将介绍基于FPGA技术和Quartus||开发平台实现十字路口交通灯控制器的一种方案。利用VHDL硬件描述语言描述各模块程序,并在Quartus||环境下编译、仿真,生成顶层文件后下载在FPGA器件EP2C8Q208C8上进行验证。验证结果表明,设计基本上实现了交通灯控制器所要求的控制过程,包括倒计时显示功能和主、支干道的红、黄、绿灯交替显示功能,表明我的设计思想是正确的。本设计采用的VerilogHDL是一种全方位的硬件描述语言具有极强的硬件描述能力,能支持系统行为级、寄存器传输级和逻辑门级三个不同层次的设计支持结构、数据流、行为三种描述形式的混合描述、覆盖面广、抽象能力强,因此在实际应用中越来越广泛。
关键词:EDA EPGA Quartus||交通灯
1
1.设计任务与要求
(1)设计一个交通信号灯控制器,由一条主干道和一条支干道汇合成十字路口,在每个入口处设置红、绿、黄三色信号灯,红灯亮禁止通行,绿灯亮允许通行,黄灯亮则给行驶中的车辆有时间停在禁行线外。
(2)红、绿、黄发光二极管作信号灯,用传感器或逻辑开关作检测车辆是否到来的信号。
(3)主干道处于常允许通行的状态,支干道有车来时才允许通行。主干道亮绿灯时,支干道亮红灯;支干道亮绿灯时,主干道亮红灯。 (4)主、支干道均有车时,两者交替允许通行,主干道每次放行45秒,支干道每次放行25秒,设立45秒、25秒计时、显示电路。 (5)在每次由绿灯亮到红灯亮的转换过程中,要亮5秒黄灯作为过渡,使行驶中的车辆有时间停到禁行线外,设立5秒计时、显示电路。
2.系统设计总体方案
整体框架思路为:首先将教学实验箱提供的50MHZ时钟信号分频,转换为可利用的1Hz CP信号,同时为了实现绿灯在1s内闪烁一次,再转换出一个2Hz的CP信号提供给需要闪烁的绿灯。然后是设置时间的功能模块,通过开关可以分别设置四个方向的运行时间,并将设置的时间传送到状态转换模块中。在状态转换功能模块中,通过前面传送来的设定通行时间进行倒计时和转换状态,并输出当前方向通行剩余时间和四向使能EN信号。在时间显示功能模块中,接收到前面
2
的设置时间、剩余时间、使能信号,运用前面说明的现实方式的逻辑,计算出等待时间,在该向通行时显示剩余时间,在该向等待时显示等待时间,最终将时间信号输出到数码管显示模块;另外,由于数码管数量的,只能一次性显示8个(即四组),那么究竟是显示倒计时还是显示设置时间就需要一个开关信号来区分,于是设置一个输入信号来判别是否进入设置模式,并且只能在设置模式下设置时间。LED信号灯显示功能模块则将状态转换模块输出的EN使能信号和2Hz的CP信号以及当前剩余时间作为输入,根据状态点亮相应的LED信号灯。LED显示功能模块的原理和LED信号灯显示模块类似,也是根据同步状态EN使能信号,通过刷新字符的方式,改变和显示当前通行状态。最后,数码管显示功能模块是结合DE2教学开发板数码管的编码规则将BCD码转换为七段码,在译码后显示出来。
3.各模块电路具体实现
3.1时钟分频模块
module div_clk(clk_50MHz,clk_1Hz,clk_1KHz,clk_500Hz); input clk_50MHz;
output clk_1Hz,clk_500Hz,clk_1KHz; reg clk_1Hz,clk_500Hz,clk_1KHz; reg [24:0] cnt1; reg [24:0] cnt2; reg [24:0] cnt3;
always @(posedge clk_50MHz) begin if(cnt1 == 24999999) begin cnt1<=0;
clk_1Hz=~clk_1Hz; end
else cnt1<=cnt1+1'b1; end
always @(posedge clk_50MHz) begin if(cnt2 == 24999)
3
begin cnt2<=0;
clk_1KHz=~clk_1KHz; end
else cnt2<=cnt2+1'b1; end
always @(posedge clk_50MHz) begin if(cnt3 == 49999)
begin cnt3<=0;
clk_500Hz=~clk_500Hz; end
else cnt3<=cnt3+1'b1; end
endmodule
3.2 十进制减法计数模块
module jiao_tong_deng(ra,ga,ya,rb,gb,yb,clk1hz,jin,qh,ql); input jin; input clk1hz;
output ra,ga,ya,rb,gb,yb; output qh,ql; reg [1:0]dig; reg [6:0]seg;
reg ra,ga,ya,rb,gb,yb; reg [1:0]state,next_state;
parameter state0=2'b00,state1=2'b01,state2=2'b10,state3=2'b11; reg [3:0]one,ten; reg [1:0]cnt; reg [3:0]data;
reg [6:0]seg_temp; reg r1,g1,y1,r2,g2,y2; reg [13:0]count1; reg [8:0]count2; reg a;
reg [3:0]qh,ql;
always @(posedge clk1hz) begin
state=next_state; case(state) state0:begin if(!jin) begin if(!a)
4
begin
qh<='b0011; ql<='b0101; a<=1; r1<=0; y1<=0; g1<=1; r2<=1; y2<=0; g2<=0; end else begin
if(!qh&&!ql) begin
next_state<=state1; a<=0;
qh<='b0000; ql<='b0000; end
else if(!ql) begin
ql<='b1001; qh<=qh-1; end else begin
ql<=ql-1; end end end end
state1:begin if(!jin) begin if(!a) begin
qh<='b0000; ql<='b0101; a<=1; r1<=0; y1<=1; g1<=0;
5
r2<=1; y2<=0; g2<=0; end else begin if(!ql) begin
next_state<=state2; a<=0;
qh<='b0000; ql<='b0000; end else begin
ql<=ql-1; end end end end
state2:begin if(!jin) begin if(!a) begin
qh<='b0010; ql<='b0100; a<=1; r1<=1; y1<=0; g1<=0; r2<=0; y2<=0; g2<=1; end else begin
if(!qh&&!ql) begin
next_state<=state3; a<=0;
qh<='b0000;
6
end end
endcase one<=ql; ten<=qh; end
always@(jin,clk1hz,r1,g1,y1,r2,g2,y2,seg_temp) begin if(jin) begin
ra<=r1||jin; rb<=r2||jin; ga<=g1&&~jin; gb<=g2&&~jin; ya<=y1&&~jin; yb<=y2&&~jin;
seg[0]<=seg_temp[0]&&clk1hz; seg[1]<=seg_temp[1]&&clk1hz; seg[2]<=seg_temp[2]&&clk1hz; seg[3]<=seg_temp[3]&&clk1hz; seg[4]<=seg_temp[4]&&clk1hz; seg[5]<=seg_temp[5]&&clk1hz; seg[6]<=seg_temp[6]&&clk1hz; end else
begin seg[6:0]<=seg_temp[6:0]; ra<=r1; rb<=r2; ga<=g1; gb<=g2; ya<=y1; yb<=y2; end end
endmodule
3.3 数码管显示及译码模块
input clk_1k; //输入时钟
input[31:28] d1; //输入要显示的数据 input[27:24] d2; input[23:20] d3;
7
input[19:16] d4; input[15:12] d5; input[11:8] d6; input[7:4] d7; input[3:0] d8;
output[7:0] dig; //数码管选择输出引脚 output[7:0] seg; //数码管输出引脚
reg[7:0] seg_r; //定义数码管输出寄存器 reg[7:0] dig_r; //定义数码管选择输出寄存器 reg[3:0] disp_dat; //定义显示数码寄存器 reg[2:0] count; //定义计数寄存器 assign dig = dig_r; //输出数码管选择 assign seg = seg_r; //输出数码管译码结果 begin
case(count) //选择扫描显示数据
3'd0 : disp_dat = d1[31:28]; //第一个数码管 3'd1 : disp_dat = d2[27:24]; //第二个数码管 3'd2 : disp_dat = d3[23:20]; //第三个数码管 3'd3 : disp_dat = d4[19:16]; //第四个数码管 3'd4 : disp_dat = d5[15:12]; //第五个数码管 3'd5 : disp_dat = d6[11:8]; //第六个数码管 3'd6 : disp_dat = d7[7:4]; //第七个数码管 3'd7 : disp_dat = d8[3:0]; //第八个数码管 default : disp_dat = 0; Endcase
case(count) //选择数码管显示位
3'd0 : dig_r = 8'b0111_1111;//选择第一个数码管显示 3'd1 : dig_r = 8'b1011_1111;//选择第二个数码管显示 3'd2 : dig_r = 8'b1101_1111;//选择第三个数码管显示 3'd3 : dig_r = 8'b1110_1111;//选择第四个数码管显示 3'd4 : dig_r = 8'b1111_0111;//选择第五个数码管显示 3'd5 : dig_r = 8'b1111_1011;//选择第六个数码管显示 3'd6 : dig_r = 8'b1111_1101;//选择第七个数码管显示 3'd7 : dig_r = 8'b1111_1110;//选择第八个数码管显示 default : dig_r = 8'b1111_1111;
endcase end
8
3.4 交通信号灯电路模块
图3.4.1 交通灯设计总电路模块
3.5 时序状态控制模块
begin
case (disp_dat) //七段译码 4'h0 : seg_r = 8'hc0; //显示\"0\" 4'h1 : seg_r = 8'hf9; //显示\"1\" 4'h2 : seg_r = 8'ha4; //显示\"2\" 4'h3 : seg_r = 8'hb0; //显示\"3\" 4'h4 : seg_r = 8'h99; //显示\"4\" 4'h5 : seg_r = 8'h92; //显示\"5\" 4'h6 : seg_r = 8'h82; //显示\"6\" 4'h7 : seg_r = 8'hf8; //显示\"7\" 4'h8 : seg_r = 8'h80; //显示\"8\" 4'h9 : seg_r = 8'h90; //显示\"9\" 4'ha : seg_r = 8'h88; //显示\"a\" 4'hb : seg_r = 8'h83; //显示\"b\" 4'hc : seg_r = 8'hc6; //显示\"c\" 4'hd : seg_r = 8'ha1; //显示\"d\" 4'he : seg_r = 8'h86; //显示\"e\" 4'hf : seg_r = 8'h8e; //显示\"f\" default: seg_r = 8'hff;//不显示 endcase End
Endmodule
9
4 . 设计测试结果
图4.1.1 时序仿真图
图4.1.2 下载结果图
5. 总结
在本设计中出现的问题有很多,比如程序的组合,一开始我只是简单的将编好的控制模块,分频模块组合在一起,进行编译的时候并没有报错,而仿真结果也是看似正确,因为只有主程序得到编译。最后一步是硬件的仿真,程序下载之后,数码管不亮,二极管也不亮,我检查程序,也没有错误,接入引脚也是正确的(虽然之前有几次是因为引脚接错位和芯片的错误使用,以及功能仿真与时序仿真的不同),启动之后就是不亮,经过反复检查,复位键和保持键有些失灵,按下几次之后即恢复正常工作,和之前期望的完全相同。 本设计中出现的错误以及查找和改正错误的过程是最大的收获,这不仅是对我知识的考察,也是一种实际应用能力的证明,经过两天
10
不间断的检查和纠正,程序才算初步成功可编译,然而对已仿真的结果常常又不能尽人意,还要时不时的修改程序已达到期望的目标,最后下载硬件的时候更是麻烦,本来仿真是完美的,可就是硬件实现出问题,这足足花了一下午的时间检查错误,程序基本没错,就是硬件失灵,按了好几次复位与保持才使程序正确运行,这是对硬件了解太少所导致的后果,以后学习检查硬件也是我学习的重点! 至此,本设计成功。
参考文献:
〔1〕谭会生,张昌凡.EDA技术及应用(第三版).西安电子科技大学出版社,2011.
〔2〕陈忠平,高金定.高见芳.基于Quartus||的FPGA/CPLD设计与实践.电子工业出版社,2010.
〔3〕刘腾红.孙细明.《信息系统分析与设计》[M]. 北京科学出版社,2003.8.
〔4〕曾强聪.Visual Basic6.0《程序设计基础教程》[M]. 清华 大学出版社,2004.5.
〔5〕江国强.《 EDA技术与应用》(第二版)[M]. 北京:电子工业出版社,2008.4.
〔6〕何元清.《电子产品设计》[M],北京北京大学出版社,2006.
11
附录
主程序源码
module decode(clk_1k,d1,d2,d3,d4,d5,d6,d7,d8,dig,seg); //模块名suan_led
input clk_1k; //输入时钟
input[31:28] d1; //输入要显示的数据 input[27:24] d2; input[23:20] d3; input[19:16] d4; input[15:12] d5; input[11:8] d6; input[7:4] d7; input[3:0] d8;
output[7:0] dig; //数码管选择输出引脚 output[7:0] seg; //数码管输出引脚
reg[7:0] seg_r; //定义数码管输出寄存器 reg[7:0] dig_r; //定义数码管选择输出寄存器 reg[3:0] disp_dat; //定义显示数码寄存器 reg[2:0] count; //定义计数寄存器 assign dig = dig_r; //输出数码管选择 assign seg = seg_r; //输出数码管译码结果
always @(posedge clk_1k) //定义上升沿触发进程 begin
count <= count +1'b1; end
always @(posedge clk_1k) begin
case(count) //选择扫描显示数据
3'd0 : disp_dat = d1[31:28]; //第一个数码管 3'd1 : disp_dat = d2[27:24]; //第二个数码管 3'd2 : disp_dat = d3[23:20]; //第三个数码管 3'd3 : disp_dat = d4[19:16]; //第四个数码管 3'd4 : disp_dat = d5[15:12]; //第五个数码管 3'd5 : disp_dat = d6[11:8]; //第六个数码管 3'd6 : disp_dat = d7[7:4]; //第七个数码管 3'd7 : disp_dat = d8[3:0]; //第八个数码管 default : disp_dat = 0; endcase
case(count) //选择数码管显示位
3'd0 : dig_r = 8'b0111_1111;//选择第一个数码管显示 3'd1 : dig_r = 8'b1011_1111;//选择第二个数码管显示
12
3'd2 : dig_r = 8'b1101_1111;//选择第三个数码管显示 3'd3 : dig_r = 8'b1110_1111;//选择第四个数码管显示 3'd4 : dig_r = 8'b1111_0111;//选择第五个数码管显示 3'd5 : dig_r = 8'b1111_1011;//选择第六个数码管显示 3'd6 : dig_r = 8'b1111_1101;//选择第七个数码管显示 3'd7 : dig_r = 8'b1111_1110;//选择第八个数码管显示 default : dig_r = 8'b1111_1111; endcase end
always @(disp_dat) begin
case (disp_dat) //七段译码 4'h0 : seg_r = 8'hc0; //显示\"0\" 4'h1 : seg_r = 8'hf9; //显示\"1\" 4'h2 : seg_r = 8'ha4; //显示\"2\" 4'h3 : seg_r = 8'hb0; //显示\"3\" 4'h4 : seg_r = 8'h99; //显示\"4\" 4'h5 : seg_r = 8'h92; //显示\"5\" 4'h6 : seg_r = 8'h82; //显示\"6\" 4'h7 : seg_r = 8'hf8; //显示\"7\" 4'h8 : seg_r = 8'h80; //显示\"8\" 4'h9 : seg_r = 8'h90; //显示\"9\" 4'ha : seg_r = 8'h88; //显示\"a\" 4'hb : seg_r = 8'h83; //显示\"b\" 4'hc : seg_r = 8'hc6; //显示\"c\" 4'hd : seg_r = 8'ha1; //显示\"d\" 4'he : seg_r = 8'h86; //显示\"e\" 4'hf : seg_r = 8'h8e; //显示\"f\" default: seg_r = 8'hff;//不显示 endcase end
endmodule
13
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- xiaozhentang.com 版权所有 湘ICP备2023022495号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务