FPGA实验报告--交通灯控制器设计院系:电子与信息工程系专业:通信工程班级:姓名:学号:指导教师:一、实验任务 1、任务名称:交通灯控制器的设计2、设计容与要求:① 设计一个十字路口交通信号灯的定时控制电路。
要求红、绿灯按一定的规律亮和灭,并在亮灯期间进行倒计时,并将运行时间用数码管/液晶显示出来。
② 绿灯亮时,为该车道允许通行信号,红灯亮时,为该车道禁止通行信号。
要求主干道每次通行时间为99秒,支干道每次通行时间为30秒。
每次变换运行车道前绿灯闪烁,持续时间为5秒。
即车道要由主干道转换为支干道时,主干道在通行时间只剩下5秒钟时,绿灯闪烁显示,支干道仍为红灯,以便主干道上已过停车线的车继续通行,未过停车线的车停止通行。
同理,当车道由支干道转换为主干道时,支干道绿灯闪烁显示5秒钟,主干道仍为红灯。
③ 对红、绿灯的运行时间要能比较方便的进行重新设置。
④ 对器件进行在系统编程和实验验证。
⑤ 用VHDL 语言对设计进行描述,设计一个测试方案,通过ISE 对设计进行仿真验证。
并能够下载到实验板上调试成功。
6 写出设计性实验报告,并打印各层次的源文件和仿真波形,然后作简要说明。
2、补充功能与要求:1.在主干道和支干道添加左转向灯;2.各灯亮的时间及最后闪烁时间可调节;3.紧急路况时,主干道和支干道都为红灯。
二、实验环境1、ISE 软件一套;2、PC 机一台。
三、设计思路1、根据题目要求,知道整个交通灯的运行过程是周期的,所以可以设计一个总的计数器,满周期则清零;2、将灯闪烁时间、主干道绿灯亮的时间、主干道转向灯亮的时间、支干道绿灯亮的时间、支干道转向灯亮的时间分别记为变量t0、t1、t2、t3、t4,通过调整它们,实现调节各灯亮的时间;3、将所有需要显示的量由同一个信号表示并最终输出、显示在LCD上。
四、系统设计a)系统框图b)状态转换说明:主干道和支干道永远有且只有一个灯亮,紧急路况时两边红灯亮,其余时候有且只有一个红灯亮;主干道绿灯、主干道转向灯亮、支干道绿灯、支干道转向灯依次亮,在最后t0S(默认为5S)闪烁。
c)输入输出及信号设计:Port ( LCD_Clk : in STD_LOGIC;----50mhz时钟reset : in STD_LOGIC:='0';--复位sensor:in std_logic :='0';---特殊情况时,两边都是红灯up:in std_logic :='0' ;---有效时调整时间时增大时间down:in std_logic :='0';---有效时调整时间时减少时间choose:in std_logic :='0';---选择调整哪一个时间control:in std_logic :='0';---有效时可以暂停,调整时间LCD_RS : out STD_LOGIC;LCD_RW : out STD_LOGIC;LCD_EN : out STD_LOGIC;redax,greenax ,greenay:out std_logic;--主干道的红灯和两个绿灯,greenay为左转灯redbx,greenbx ,greenby:out std_logic;--支干道的红灯和两个绿灯,greenby为左转灯data : out STD_LOGIC_VECTOR (3 downto 0)); --Lcd显示type istate is(write_instr,write_dataup4,write_datadown4,set_addrup,set_addrdown,ret_homeup,ret_homedown);signal state:istate;signalt_clk,clk500:std_logic;---分别为1hz,500hzsignalt:integer range 0 to 15:=0;signaltnumh,cntnuml:integer range 0 to 9;--输入到数码管的数字signal countnum:integer ;---计数器signal reda,greena,greena1,redb,greenb,greenb1:std_logic;--各交通灯对应的信? signal t:integer range 0 to 99;---要输入lcd中的数字d)基本模块设计:1)字符译码函数function putc(data:character) return std_logic_vector is---字符译码函数,将字符显示在lcd上variable result:std_logic_vector(7 downto 0);begincase data iswhen 'o'=> result:=conv_std_logic_vector(111,8);when 'u'=> result:=conv_std_logic_vector(117,8);when 'C'=> result:=conv_std_logic_vector(67,8);when 'n'=> result:=conv_std_logic_vector(110,8);when 't'=> result:=conv_std_logic_vector(116,8);when 'e'=> result:=conv_std_logic_vector(101,8);when 'r'=> result:=conv_std_logic_vector(114,8);when ':'=> result:=conv_std_logic_vector(58,8);when others => result:=conv_std_logic_vector(32,8);end case;return result;end putc;2)数字译码函数function putn(num:in integer range 0 to 9) return std_logic_vector is---数字译码函数,将数字显示在lcd上variable fig:std_logic_vector(7 downto 0);begincase num iswhen 0=> fig:="00110000";when 1=> fig:="00110001";when 2=> fig:="00110010";when 3=> fig:="00110011";when 4=> fig:="00110100";when 5=> fig:="00110101";when 6=> fig:="00110110";when 7=> fig:="00110111";when 8=> fig:="00111000";when 9=> fig:="00111001";end case;return fig;end putn;3)分频,由50Mhz得到500hz,驱动lcd process(LCD_Clk)----分频,得到500hz时钟variable n3:integer range 0 to 49999;beginif rising_edge(LCD_Clk) thenif n3<49999 thenn3:=n3+1;elsen3:=0;clk500<=not clk500;end if;end if;end process;4)分频,由500hz得到1hz,作为交通灯控制器输入process(clk500)----分频,得到1hz时钟variable n:integer range 0 to 249;beginif rising_edge(clk500) thenif n<249 thenn:=n+1;elsen:=0;cnt_clk<=nott_clk;end if;end if;end process;5)主要功能实现:process(cnt_clk,reset,choose,up,down,control,t)---实现各种要求功能,包括倒计时显示,红绿灯(含左转灯)转换,以及转换时间调整variable m:integer range 0 to 4 ;---m表示转换的是哪一个时间(t0-t4中哪一个)variable count : natural range 0 to 99;---计数器,将正计数转换为倒计数variable t0:integer range 0 to 99 :=5;---绿灯闪烁时间variable t1:integer range 0 to 99 :=79;---主干道绿灯亮的时间variable t2:integer range 0 to 99 :=20;---主干道左转灯亮的时间variable t3:integer range 0 to 99:=20;---支干道绿灯亮的时间variable t4:integer range 0 to 99:=10;---支干道左转灯亮的时间beginif reset='1' then --1----复位,计数器清零,m,t0-t4赋初值countnum<=0;m:=0;t0:=5;t1:=79;t2:=20;t3:=20;t4:=10;elsif control='1' then--可调节时间或暂停if rising_edge(cnt_clk) then --2if choose ='1' then –选择t0-t4中的哪一个 3if m=4 then --4m:=0;---m在0-4之间循环elsem:=m+1;end if; --4t<=m;--显示melse --choose为0时调节所选时间3if up='1' then --tx增大--4if m =0 then --调整t0,即闪烁时间,上限为7s,5if t0=7 then --6t0:=5;elset0:=t0+1;end if; --6t<=t0;--显示t0elsif m=1 then--调整t1,上限99s if t1=99 then --6t1:=79;elset1:=t1+1;end if; --6t<=t1;--显示t1elsif m=2 then--调整t2,上限为30s if t2=30 then --6t2:=20;elset2:=t2+1;end if; --6t<=t2;--显示t2elsif m=3 then --调整t3,上限为30s if t3=30 then --6t3:=20;elset3:=t3+1;t<=t3;--显示t3elsif m=4 then--调整t4,上限为15sif t4=15 then --6t4:=10;elset4:=t4+1;end if; --6t<=t4;--显示t4end if; --5elsif down='1' then --tx减小4if m =0 then ----调整t0,即闪烁时间,下限为2s,5if t0=2 then --6t0:=5;else t0:=t0-1;end if; --6t<=t0;---显示t0elsif m=1 then----调整t1,下限为39秒if t1=39 then --6t1:=79;else t1:=t1-1;t<=t1;--显示t1elsif m=2 then ----调整t2,下限为10s if t2=10 then --6t2:=20;else t2:=t2-1;end if; --6t<=t2;---显示t2elsif m=3 then -----调整t3,下限10s if t3=10 then --6t3:=20;else t3:=t3-1;end if;--6t<=t3;---显示t3elsif m=4 then----调整t4,下限8sif t4=8 then --6t4:=10;else t4:=t4-1;end if;--6t<=t4; --显示t4end if; --5end if; --4end if; --3end if; --2elsif rising_edge(cnt_clk) then --此时reset=0if countnum=t1+t2+t3+t4 then --2记数到整周期时,记数器清零countnum<=0;elsecountnum<=countnum+1; ---计数器小于整周期时,正常记数end if; --2if sensor='1' then --2 sensor信号有效期间,表示紧急情况两组路灯都为红灯reda<='1';redb<='1';greena<='0';greenb<='0';greena1<='0';greenb1<='0';elseif countnum<=t1-t0 then--3主干道绿灯亮且非闪烁,支干道红灯亮reda<='0';greena<='1';greena1 <= '0';redb<='1';greenb<='0';greenb1<='0';elsif countnum<=t1 then --主干道绿灯亮且闪烁,支干道红灯亮reda<='0';greena<=not greena;greena1<= '0';redb<='1';greenb<='0';greenb1<='0';elsif countnum<=t1+t2-t0 then --主干道左转绿灯亮且非闪烁,支干道红灯亮reda<='0';greena<='0';greena1 <= '1';redb<='1';greenb<='0';greenb1<='0';elsif (countnum<=t1+t2) then --主干道左转绿灯亮且闪烁,支干道红亮reda<='0';greena<='0';greena1 <= not greena1;redb<='1';greenb<='0';greenb1<='0';elsif (countnum<=t1+t2+t3-t0) then --支干道绿灯亮且非闪烁,主干道红灯亮reda<='1';greena<='0';greena1 <= '0';redb<='0';greenb<='1';greenb1<='0';elsif (countnum<=t1+t2+t3) then --支干道绿灯亮且闪烁,主干道红灯亮reda<='1';greena<='0';greena1 <= '0';redb<='0';greenb<=not greenb;greenb1<='0';elsif (countnum<=t1+t2+t3+t4-t0) then --支干道左转绿灯亮且非闪烁,主干道红灯亮reda<='1';greena<='0';greena1 <= '0';redb<='0';greenb<='0';greenb1<='1';elsif (countnum<=t1+t2+t3+t4) then --支干道左转绿灯亮且闪烁,主干道红灯亮reda<='1';greena<='0';greena1 <= '0';redb<='0';greenb<='0';greenb1<=not greenb1;end if; --3end if; --2----下面将正计数转换为倒计数-----if countnum<=t1 then --2count:=t1-countnum; ---主干道绿灯亮,支干道红灯亮时倒计时elsif countnum<=t1+t2 then ---主干道左转绿灯亮,支干道红灯亮时倒计时count:=t1+t2-countnum;elsif countnum<=t1+t2+t3 then----支干道绿灯亮,主干道红灯亮时倒计时count:=t1+t2+t3-countnum;elsif countnum<=t1+t2+t3+t4 then---支干道左转绿灯亮,主干道红灯亮时倒计时count:=t1+t2+t3+t4-countnum;end if; --2----上面将正计数转换为倒计数----t<=count;---显示countend if; --1-----以下代码为分位译码-----if t>=90 then --1cntnumh<=9;cntnuml<=t-90;elsif t>=80 thencntnumh<=8;cntnuml<=t-80;elsif t>=70 thencntnumh<=7;cntnuml<=t-70; elsif t>=60 thencntnumh<=6;cntnuml<=t-60; elsif t>=50 thencntnumh<=5;cntnuml<=t-50; elsif t>=40 thencntnumh<=4;cntnuml<=t-40; elsif t>=30 thencntnumh<=3;cntnuml<=t-30; elsif t>=20 thencntnumh<=2;cntnuml<=t-20; elsif t>=10 thencntnumh<=1;cntnuml<=t-10; elsecntnumh<=0;cntnuml<=t;end if;--1-----以上代码为分位译码--------各信号赋给各输出的交通灯greenax<=greena;----主干绿灯greenay<=greena1;---主干左转绿灯greenbx<=greenb;---支干道绿灯greenby<=greenb1;---支干道左转绿灯redax<=reda;----主干红灯redbx<=redb;--支干道绿灯end process;主要功能仿真如下:a)、reset为1时,初始化。