基于VHDL设计的交通灯系统
采用VHOL语言进行行为描述.设计一个实用的交通灯系统,给出时序仿真波形,并下载到FPGA板进行验证实验。通过实验证明此系统能较好地达到设计的各种功能,包括倒计时时间显示功能,数字键盘操作快速调整时间功能,深夜黄灯长亮提醒功能和紧急状况下的红灯常亮功能。
一.系统功能要求
设计一个能够显示倒计时间并可人为调整时间的交通灯系统。南北方向为主干道.东西方向为支干道。比如.南北方向为直行绿灯亮20秒.黄灯亮5秒.左拐绿灯亮为15秒,黄灯亮5秒.红灯亮65秒(为东西方向直行绿灯、左拐绿灯亮及黄灯亮的时间的总合),东西方向为直行绿灯亮40秒,直行绿黄灯为5秒左拐绿灯亮15秒,黄灯亮5秒红灯45亮秒(为东西方向直行绿灯、左拐绿灯亮及黄灯亮的时间的总合).其中南北方向和东西方向的直行绿灯和左拐绿灯在最后3秒会闪烁.以提示行驶中在远处无法看清时间显示的司机通行时间快要结束了。以上红绿灯时间为预设时间。能够通过键盘操作实现时间的快速更改.更改完成后系统可立即执行更改后的时间进行运行。系统还具有深夜两方向黄灯一直闪亮警告状态(在凌晨转为正常工作)和紧急情况下的红灯常亮状态这两种状态通过人为设置。发生紧急情况时计时停止.解除后可立即继续当前的工作。
二.系统功能实现
整个系统控制由FPGA芯片来完成。时间显示采用数码管动态扫描方式,时间更改通过数字键盘实现.正常工作状态到时间更改状态和红黄灯常亮状态的改变通过拨码开关来实现。采用芯片板上g个发光二极管的其中8个模拟交通灯由于二极管数t有限.故两个方向各只用一套交通灯。系统描述采用多个进程并行处理的方式来实现.进程与进程之间通过内部信号关联。进程P1将ZOMHz的主时钟分频为ZMHz。进程P2用于再分频和按键扫描二将
ZMHz分频为供数码管扫描用的128Hz和倒计时用的IHz以及绿灯左拐灯闪烁的ZHz.同时产生用于按键行扫描的两位二进制码。进程P3用于键值获取,通过将按键扫描码和去抖
后的键值合并且译码来得到正确的键值。P4进程为码值转换和调时时间设置电路通过计数器ad一ust的自加进入相应的时间设置语句。当adjust=000时给东西方向的红灯设置倒计时间adjust“001时给东西方向的黄灯设置时间,以此类推直到。djust二111.8个交通灯的时间设置完成。内部信号time保存的值为普通二进制码,此码是通过转换函数日CO_t。_binar将键盘输入的8位日CO码转换为普通二进制码得到的。进程中设置标志位Pre是为了在pre=
O时将预设时间值赋给各灯。Pre的赋值由拨码开关来实现。P5进程是东西方向工作状态时间转换电路。每来一个。服,hz时钟通过判断tlme多nemer和yel的值来决定东西方
向系统工作在正常指挥状态.紧急状态还是深夜状态。正常指挥状态中内部不同状态的转换是通过counta的自加来实现的。当东西方向时间计数器atime减为O时counta自加。并产生相应的状态提示码eheeka。rime_en,emer和yel的赋值由拨码开关来实现。P6为东西方向工作状态亮灯转换电路。每来一个clkZhz时钟判断time_en.emer和yel的值来决定东西方向系统工作在正常指挥状态.紧急状态还是深夜状态。P6和P5分开进行的主要原因是考虑到绿灯和左拐灯在最后的3秒时刻要进行闪烁,其状态为0.5秒亮0.5秒灭,这比P5的lhz时钟快一倍故灯状态的转变只能单独用另一个Zhz的时钟控制。在进入3秒区时.通过将绿灯及左拐灯的码值取非来达到闪烁的效果。
灯状态转换的真值表如下表
P7、P8为南北方向的工作状态时间转换电路及亮灯转换电路,其原理与P5、P6相同这里就不再赘述。p9、P10、Pll构成数码管动态显示电路。p9是动态扫描计数器产生电路。p1o为码值转换和显示电路,通过调用转换函数binar_to_BCD将普通二进制码atime和
伽e转换为。位Bc。码。显示电路分为工作显示和时间设置显示两部分。工作显示时通过计数器cnt4进行数码管位码的赋值.从而不断循环点亮4位数码管分别显示东西和南北方向的时间。时间设皿显示时通过计数器cnt3进行位码斌值,循环点亮三位数码管显示设皿的
时间值和设置提示。P9为数码管段码译码电路。pll为移位寄存器电路.用来保存通过数字键盘输入得到的8位日C。码转换函数的原理很简单。7位二进制码与8位日CO码从10进制角度来看个位都是相同的.仅10位不同。故可以将7位二进制码减去与此码十位相同个位
为0的二进制码.从而保留了个位,再补上10位相应的二进制码即可。比如说95的二进制为1101111,将其减去90的二进制码1011010.得个位为101.即5.再补上10位1001,变为10010101,即为8位BCO码。反转换函数原理可以此类推。此外.程序中还通过去抖动模块debunce来处理数字键盘人为输入时产生的不稳定的抖动信号。
三.系统功能框图
系统由按键输入及去抖电路、移位寄存电器电路、分频电路、码值转换与调时电路、码值转换与显示电路和东西、南北工状态转换电路组成。
作
四.关键控制的源程序
码值转换与调时电路
P4:Proeess(enter,ewadiust)
begin
if(enter'event and enter='1') then
--每按一次按键
time<=BCD_to_binar(D):
case adjust is --按键计数器
when "000"=>ayt<=time(3 downto 0);
--东西黄灯时间赋值
when "001"=>agt<=time(5 downto 0);
--东西绿灯时间赋值
when "010"=>alt<=time(5 downto 0);
--东西左拐灯时间赋值
when "011"=>byt<=time(3 downto 0);
--南北黄灯时间赋值
when "100"=>bgt<=time(5 downto 0):
--南北绿灯时间赋值
when "101"=>blt<=rime(5 downto
0);art<=byt+bgt+blt;brt<=agt+alt+ayt;--南北左拐灯
时间赋值,东西红灯时间自动赋值,南北红灯时间自动赋
值
whenothers=>null;
end case;
if (adjust=” 101” )then adjust<=” 000”
else adjust<=adjust+1;
end if:
end if;
if pre=’ 0’ then ---如果pre为0.采用预设值
art<=” 0101000” ; ayt<=” 0101” ; agt<=” 101101” ;
alt<=” 001111” ;
brt<="100001";byt<=” 0101” , bgt<="010100";
blt="001111";
end if;
end Proeess P4:
2.东西方向工作状态时间转换程序
P5:Proeess(time_en.clk)
Variable ecounta:std_logie_veetor(2 downto 0);
begin
if (eIk’eventandelk=’ 1’ )then
if (time_ en=’ 1’ ) then ----工作状态
if (emer=’ 1’ ) the ----状态
atime (6 downro 0)<=” 0000000” ;----工作状态回0
Counta=” 000” ;
Elseif (yel=’ 1’ ) then-----警告状态
Atime (6 downto 0)<=” 000000” :一工作状态回0:
Counta=” 000” ;
else
if(atime=” 000000” ) then
Case counta is
When” 000” =>atime(5 downto 0)<=agt一1:
checka<=” 000” ;---东西绿灯时间
When” 001” =>atime(3 downto 0)<=ayt一1:
checka<=” 001” ;一东西黄灯时间
when” 010” =>atime(5 downto 0)(=alt一1:
checka<=” 001” ;----东西左拐灯时间
when” 011 ” =>atime(3downroo)<=ayt一1:
checka<=” 011” 一东西黄灯时间
when” 100” =>atim<(=art一1;checka<=” 100” ;
一东西红灯时间
When” 101” =>at1me(3 downto 0)<=ayt一1:
Checka<=” 101” 一东西黄灯时间
When
others=>null
end case
if
(counta=” 101” ) then
Counta =” 000”
else
counta:= counta+1;一状态转换
end if
else
atime<=atime一1;----倒计时
end if
end if
end if;
end if;
end Proeess P5;
3.东西方向工作状态亮灯转换程序
P6:Proeess(clk)
begin
ewled<=temPa;
if(clk’even and clk=’ 1’ ) then
if (time_en=’ 1’ ) then
if (emer=’ 1’ ) then
---紧急情况
Whenothers=>null
temPa <=” 1011”
elseif (yel=’ 1’ )then一一深夜情况
temPa<=’ 1111’ ;
tempa(1)<=not ternpa(1);一黄灯闪烁
else
case checka is
when “ 000” => -----东西绿灯状态
If (atime>” 0000011” ) then ------时间>3秒
Tempa<=” 1110” -----绿灯长亮
Elseif(atime>=” 0000000” )then----时间<=3秒
Tempa(0)<=not tempa(0); -----绿灯闪烁
End if;
When “ 001” |” 011” |” 101” =>tempa<=” 1101” ;-----
东西黄灯状态
When” 010” => ------东西左拐灯
If(atime>” 0000011” )then -----时间>3秒
Tempa<=” 0111” ;----左拐灯长亮
Elseif(atime>=” 0000000” )then
Tempa(3)<=not tempa(3);
End if;
When “ 100” =>tempa<=” 1011” ;
When others=>null;
End case;
End if;
End if;
End if;
End process;
4.南北方向上的工作状态时间转换电路和工作状态亮
灯转换程序与东西方向差不多一样,故省略。
5.数码管动态显示电路
P9:Proeess(clk128hz)
begin
if clk128hz‘even tand clk128hz= ‘ 1’ then
ent4<=ent4+1: -----工作显示
位码扫描
ent3<=ent3+1; -----调时显示
位码扫描
If cnt3=” 10” then
Cnt3<=” 00”
End if;
End if;
End process p7;
P10: Process(time_en,atime,btime,time,cnt4,cnt3)
begin
if(time_en=’ 1’ ) then
atimedisp<=h_d (atime);一将7位二进制转换为8位BCD码
Btimedisp(=h_d(btime);
Ease cnt4 is
When” 00” => BT<=” 0000001”
db<=atimedisp(3 downto 0);一扫描显示4位数码管
when ‘ 01 ’ =>BT<=” 0000010”
;db<=atimedlsP(7 downto 4):
when” 10 ” =>BT<=” 010000”
:db(=btimedisP(3 downto 0);
When” 11” =>BT<=” 100000”
:db<=bitimedisp (7 downto 4):
When others=>null
end Case.
else
case Cnt3 is
when” 00” >=bt <=” 0000100” ;db<=D(3 downto 0);----一扫描显示3位数码管
when “ 01” =>BT<=” 0001000” db<=D(7 downto 4);
when” 10” =>BT<=” 0010000” );db<=ewadjust+1:一调时提示数码管
when others =>null
end Case
End if
end Proeess P10
p11;process(db)
begin
case db is---段码编码
when “ 0000” =>SEGOUT<=” 0000110” ;------0
when “ 0001” =>SEGOUT<=” 1011011” ;------1
when “ 0010” =>SEGOUT<=” 1001111” ;------2
when “ 0011” =>SEGOUT<=” 1100110” ;------3
when “ 0100” =>SEGOUT<=” 1101111” ;------4
when “ 0101” =>SEGOUT<=” 1101101” ;------5
when “ 0110” =>SEGOUT<=” 1101111” ;------6
when “ 0111” =>SEGOUT<=” 0000111” ;------7
when “ 1000” =>SEGOUT<=” 1111111” ;------8
when “ 1001” =>SEGOUT<=” 1101111” ;------9
When others=>SEGOUT<=”XXXXXXX”;
End Case
五.波形仿真
由于系统较为复杂.若直接用源程序进行仿真,无法从波形图中反映其工作状态。故仿真时简化了电路.用clkout表示IHz的脉冲.elk表示2Hz的时钟。eweounter和SncoUnte湿示当前的时间状态。如图2,开始时系统处于正常工作状态,ewled为1110,即东西方向绿灯亮,snled为01111,即南北方向红灯亮。当进入深夜情况,即yel为1时.ewled轮流变为1101和1111.snled轮流变为1011!,即东西和南北方向黄灯闪烁,同时时间回O。深夜情况结束后,系统重新回到正常工作状态。紧急情况类似,不同的是红灯进入长亮状态。绿灯闪烁状态如图3。可见进入3秒区后,ewled轮流变为飞111和1110,即为绿灯闪烁。此两波形图出现的灯与时间变化不同步是由于为便于波形仿真而简化程序。clkout时钟是每来一个clk上升沿产生的.如果如完整程序那样分频产生就不会出现这种状况。调试时工作状
态的波形仿真从图上很难看出其是否运行正常.