基于VHDL语言交通信号灯设计
来源:银行招聘 发布时间:2020-09-11 点击:
交通信号控制器的 L VHDL 的设计
1. 设计任务
模拟十字路口交通信号灯的工作过程,利用实验板上的两组红、黄、绿 LED作为交通信号灯,设计一个交通信号灯控制器,示意图如图 1-1 所示。要求:
(1)
交通灯从绿变红时,有 4 秒黄灯亮的间隔时间; (2)
交通灯红变绿是直接进行的,没有间隔时间; (3)
主干道上的绿灯时间为 40 秒,支干道的绿灯时间为 20 秒; (4)
在任意时间,显示每个状态到该状态结束所需的时间。
支干道
主干道
图 1-1 路口交通管理示意图 表 1-1 交通信号灯的 4 种状态
A B C D 主干道交通灯 绿(40 秒)
黄(4 秒)
红(20 秒)
红(4 秒)
支干道交通灯 红 红 绿 黄
. 2. 设计要求
采用VHDL语言编写程序,并在QuartusII工具平台中进行开发,下载到EDA实验箱进行验证。
编写设计报告,要求包括方案选择、程序清单、调试过程、测试结果及心得体会。
. 3. 设计方案
CLK
时间显示数据输出
信号灯输出
图 3-1 交通信号灯控制器程序原理框图
进程将 CLK 信号分频后产生 1 秒信号,然后构成两个带有预置数功能的十进制计数器,并产生允许十位计数器计数的控制信号。状态寄存器实现状态转换和产生状态转换的控制信号,下个模块产生次态信号和信号灯输出信号,以及每一个状态的时间值。经过五个模块的处理,使时间计数、红绿灯显示能够正常运行。程序原理图如图 3-1 所示。
. 4. 各模块具体设计
秒脉冲信号发生器 计数器
状态寄存器
次态发生器 信号灯输出信号
4.1 顶层文件的设计
顶层文件的原理图可以依据系统的框图进行,由控制模块 JTD_CTRL、计时模块 JTD_TIME、译码驱动模块 JTD_LIGHT、显示模块 JTD_DIS 和分频模块JTD_FQU 五部分组成,其顶层原理图文件如图 3-1 所示。
图 4-1 交通灯顶层文件原理图 顶层模块的程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY TRAFFIC IS PORT(
CLK1K,CLR:IN STD_LOGIC;
M:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
SEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
ABL:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
); END TRAFFIC; ARCHITECTURE BEHAVE OF TRAFFIC IS COMPONENT JTD_FQU IS
--分频器元件的例化 PORT(
CLK1K:IN STD_LOGIC;
CLK:OUT STD_LOGIC
); END COMPONENT; COMPONENT JTD_DIS IS
--数码显示的元件例化 PORT(
CLK1K,CLK,CLR:IN STD_LOGIC;
M:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
AT,BT:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
SEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
); END COMPONENT; COMPONENT JTD_LIGHT IS
--译码驱动的元件例化 PORT(
CLR:IN STD_LOGIC;
M,S:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
ABL:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
); END COMPONENT; COMPONENT JTD_TIME IS
--计时元件的例化 PORT(
CLK,CLR:IN STD_LOGIC;
M,S:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
AT,BT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
); END COMPONENT; COMPONENT JTD_CTRL IS
--控制模块的元件例化 PORT(
CLK,CLR:IN STD_LOGIC;
AT,BT:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
M:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
S:OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
); END COMPONENT; SIGNAL CLK:STD_LOGIC; SIGNAL AT:STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL BT:STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL S:STD_LOGIC_VECTOR(2 DOWNTO 0); BEGIN
U1:JTD_FQU PORT MAP(
--名字关联方式赋值
CLK1K=>CLK1K,
CLK=>CLK
); U2:JTD_TIME PORT MAP(
CLR=>CLR,
AT=>AT,
BT=>BT,
CLK=>CLK,
M=>M,
S=>S
); U3:JTD_CTRL PORT MAP(
M=>M,
S=>S,
CLK=>CLK,
CLR=>CLR,
AT=>AT,
BT=>BT
);
U4:JTD_DIS PORT MAP(
CLK1K=>CLK1K,
CLK=>CLK,
CLR=>CLR,
AT=>AT,
BT=>BT,
LED=>LED,
SEL=>SEL,
M=>M
); U5:JTD_LIGHT PORT MAP(
CLR=>CLR,
S=>S,
ABL=>ABL,
M=>M
); END BEHAVE; 4.2 控制模块 JTD_CTRL 的设计
控制的模块根据外部输入信号 M2~M0 和计时模块 JTD_TIME 的输入信号,产生系统的状态机,控制其他部分协调工作。控制模块的源文件程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY JTD_CTRL IS PORT(
CLK,CLR:IN STD_LOGIC;
M:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
--用M来表示系统的8种工作状态
AT,BT:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
S:OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
);
END JTD_CTRL;
ARCHITECTURE JTD_1 OF JTD_CTRL IS
SIGNAL Q:STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
PROCESS(CLR,CLK,M,AT,BT)
BEGIN
IF CLR="1"THEN Q<="000";
--清"0"处理
ELSIF(CLK"EVENT AND CLK="1")THEN
--时钟上升沿信号一来,M 控制系统的 8 种状态
IF M="000"THEN Q<="001";
END IF;
IF M="001"THEN Q<="011";
END IF;
IF M="010"THEN Q<="101";
END IF;
IF M="011"THEN Q<="111";
END IF;
IF M>="100"THEN
IF(AT=X"01")OR(BT=X"01")THEN Q<=Q+1;
ELSE Q<=Q;
END IF;
END IF;
END IF;
END PROCESS;
S<=Q;
--M 的控制端转向控制口 S
END JTD_1; 该模块的时序仿真和功能仿真波形图如图 4-2
图 4-2 功能仿真 4.3 计时模块 JTD_TIME 的设计 计时模块用来设定 A 和 B 两个方向计时器的初值,并为显示模块 JTD_DIS
提供倒计时时间。当正常计时开始后,需要进行定时计数操作,由于东西和南北两个方向上的时间显示器是由两个 LED 七段显示数码管组成的,因此需要产生两个 2 位的计时信息:2 个十位信号,2 个个位信号,这个定时计数操作可以由一个定时计数器来完成,又因为交通灯的状态变化是在计时为 0 的情况下才能进行的,因此需要一个计时电路来产生使能信号,因此定时计数的功能就是用来产生 2 个 2 位计时信息和使能信号。
计时模块的源文件程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY JTD_TIME IS PORT(
CLK,CLR:IN STD_LOGIC;
M,S:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
AT,BT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
); END JTD_TIME; ARCHITECTURE JTD_2 OF JTD_TIME IS
SIGNAL AT1,BT1:STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL ART,AGT,ALT,ABYT:STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL BRT,BGT,BLT:STD_LOGIC_VECTOR(7 DOWNTO 0); BEGIN
ART<=X"55"; --ART<=‚‛ A 方向红灯亮
AGT<=X"40"; --AGT<=‚‛A 方向绿灯亮
ALT<=X"15"; --ALT<=‚‛灯间歇闪烁
ABYT<=X"05";--ABYT<=‚‛AB 两方向黄灯亮
BRT<=X"65";--BRT<=‚‛B 方向红灯亮
BGT<=X"30";--BGT<=‚‛B 方向绿灯亮
BLT<=X"15";--BLT<=‚‛B 方向灯闪烁
PROCESS(CLR,CLK,M,S)
BEGIN
IF CLR="1"THEN AT1<=X"01";BT1<=X"01";
ELSIF (CLK"EVENT AND CLK="1")THEN
IF M="000"THEN AT1<=X"01";BT1<=X"51";--M=0 时,A 方向的计时器计时,B 方向的红灯亮
END IF;
IF M="001"THEN AT1<=X"01";BT1<=X"06";--M=1 时,A 方向的计时器计时,B 方向绿灯亮
END IF;
IF M="010"THEN AT1<=X"41";BT1<=X"01";--B 方向的计时器计时,A 方向的黄灯亮
END IF;
IF M="011"THEN AT1<=X"06";BT1<=X"01";--B 方向的计时器计时,A 方向的红灯亮
END IF;
IF M>="100"THEN
IF(AT1=X"01")OR(BT1=X"01")THEN
CASE S IS
WHEN"000"=>AT1<=ALT;BT1<=BRT;--当 S=0 时,AB两方向的计时器计时,A 方向车左转,B 方向的红灯亮
WHEN"001"=>AT1<=ABYT;--当 S=1 时,A 方向计时器计时,A 方向黄灯亮
WHEN"010"=>AT1<=AGT;--当 S=2 时,A 方向计时器计时,A 方向绿灯亮
WHEN"011"=>AT1<=ABYT;--当 S=3 时,AB 两方向黄灯亮,A 方向计时器计时
WHEN"100"=>AT1<=ART;BT1<=BLT;--当 S=4 时,A 方向计时,红灯亮,B 方向车左转,B 方向计时器计时
WHEN"101"=>BT1<=ABYT;--当 S=5 时,B 方向计时器计时,AB 两方向黄灯亮
WHEN"110"=>BT1<=BGT;--当 S=6 时,B 方向计时器计时,B 方向绿灯亮
WHEN"111"=>BT1<=ABYT;--当 S=7 时,B 方向计时器计时,AB 两方向车右转
WHEN OTHERS=>AT1<=AT1;BT1<=BT1;
END CASE;
END IF;
IF AT1/=X"01"THEN
IF AT1(3 DOWNTO 0)="0000"THEN
AT1(3 DOWNTO 0)<="1001";--第四位数码管显示
AT1(7 DOWNTO 4)<=AT1(7 DOWNTO 4)-1;高四位数码管减一显示
ELSE AT1(3 DOWNTO 0)<=AT1(3 DOWNTO 0)-1;低四位数码管减一显示
AT1(7 DOWNTO 4)<=AT1(7 DOWNTO 4);高四位数码管显示不变
END IF;
END IF;
IF BT1=X"01"THEN
IF BT1(3 DOWNTO 0)="0000"THEN
BT1(3 DOWNTO 0)<="1001";--B 方向计数器低四位数码管显示‘9’
BT1(7 DOWNTO 4)<=BT1(7 DOWNTO 4)-1;--B 方向计数器高四位数码管减一计数
ELSE BT1(3 DOWNTO 0)<=BT1(3 DOWNTO 0)-1;-B 方向计数器低四位数码管减一计数
BT1(7 DOWNTO 4)<=BT1(7 DOWNTO 4);
END IF;
END IF;
END IF;
END IF; END PROCESS;
AT<=AT1;
BT<=BT1; END JTD_2;
该模块是为节省资源而设的,实验中有四个 LED 七段数码管显示计数,点亮一个 LED 需电流 5-50mA,同时点亮 4 个 LED,CPLD 可能无法负荷这样的电流驱动,而且功率太大,散热也是问题。同时这么做也容易造成电路被烧毁,因此需要逐个循环点亮。又为使显示结果持续不致闪烁抖动,只需每个扫描频率超过人眼视觉暂留频率 24Hz 以上,就能达到。选择 1kHz 作为时钟,分到 4 个数码管,每个数码管 50Hz(大于 24Hz),故不会有闪烁。
该模块的功能仿真波形图如图 4-4 所示
图 4-4 功能仿真 4.4 译码驱动模块 JTD_LIGHT 的设计 译码驱动模块根据控制信号,驱动交通灯的显示。该模块的源程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY JTD_LIGHT IS PORT(
CLR:IN STD_LOGIC;
M,S:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
ABL:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
); END JTD_LIGHT; ARCHITECTURE JTD_3 OF JTD_LIGHT IS
SIGNAL LT:STD_LOGIC_VECTOR(7 DOWNTO 0); BEGIN
PROCESS(CLR,S,M) BEGIN
IF CLR="1"THEN LT<="00000000";
--清"0"时系统状态全部处于关闭状态
ELSE IF M="000"THEN LT<="10000001";
END IF;
IF M="001"THEN LT<="00100001";
END IF;
IF M="010"THEN LT<="00011000";
END IF;
IF M="011"THEN LT<="00010010";
END IF;
IF M>="100"THEN
CASE S IS
--八种情况下的状况显示
WHEN"000"=>LT<="00010100";
WHEN"001"=>LT<="10000001";
WHEN"010"=>LT<="01000001";
WHEN"011"=>LT<="00100001";
WHEN"100"=>LT<="01000001";
WHEN"101"=>LT<="00011000";
WHEN"110"=>LT<="00010100";
WHEN"111"=>LT<="00010010";
WHEN OTHERS=>LT<=LT;
END CASE;
END IF;
END IF;
END PROCESS; ABL<=LT; END JTD_3; 该模块的功能仿真波形图如图 4-5:
图 4-5 功能仿真
4.5 显示模块 JTD_DIS 的设计
显示模块用来显示倒计时时间和系统的工作状态。其输出用来驱动六位数码管,其中四位用于显示倒计时时间,两位显示工作状态,采用动态扫描显示。该模块的源程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY JTD_DIS IS PORT(
CLK1K,CLK,CLR:IN STD_LOGIC;
M:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
AT,BT:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
LED:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
SEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
); END JTD_DIS; ARCHITECTURE JTD_4 OF JTD_DIS IS
SIGNAL OU,STL,STH,MM:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL DIS,DS:STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL SL:STD_LOGIC_VECTOR(2 DOWNTO 0); BEGIN
MM<="0"&M;
STH<=X"A";
PROCESS(CLR,CLK1K)
BEGIN
IF CLR="1"THEN SL<="000";
ELSIF(CLK1K"EVENT AND CLK1K="1")THEN
IF SL="101"THEN SL<="000";
--清"0"
ELSE SL<=SL+1;
--计数
END IF;
END IF;
END PROCESS;
PROCESS(SL)
BEGIN
CASE SL IS
--数码管的位选
WHEN"000"=>OU<=BT(3 DOWNTO 0);
WHEN"001"=>OU<=BT(7 DOWNTO 4);
WHEN"010"=>OU<=AT(3 DOWNTO 0);
WHEN"011"=>OU<=BT(7 DOWNTO 4);
WHEN"100"=>OU<=STL;
WHEN"101"=>OU<=STH;
WHEN OTHERS=>OU<=X"0";
END CASE;
END PROCESS;
PROCESS(OU)
BEGIN
CASE OU IS
--数码管的译码
WHEN X"0"=>DS<="00111111";
--显示"0"
WHEN X"1"=>DS<="00000110";
--显示"1"
WHEN X"2"=>DS<="01011011";
--显示"2"
WHEN X"3"=>DS<="01001111";
--显示"3"
WHEN X"4"=>DS<="01100110";
--显示"4"
WHEN X"5"=>DS<="01101101";
--显示"5"
WHEN X"6"=>DS<="01111100";
--显示"6"
WHEN X"7"=>DS<="00000111";
--显示"7"
WHEN X"8"=>DS<="01111111";
--显示"8"
WHEN X"9"=>DS<="01101111";
--显示"9"
WHEN OTHERS=>DS<="00000000";
END CASE;
END PROCESS; PROCESS(MM,CLK) BEGIN
IF MM>=X"4"THEN STL<=X"5";
--数码管产生进位
ELSE STL<=MM+1;
END IF;
IF CLR="1"THEN DIS<=X"00";
ELSIF MM>=X"4"THEN DIS<=DS;
ELSIF SL<="100"THEN
IF CLK="0"THEN DIS<=DS;
ELSIF DIS<=X"00"THEN
END IF;
ELSE DIS<=DS;
END IF; END PROCESS; LED<=DIS(6 DOWNTO 0); SEL<=SL; END JTD_4;
该模块的功能仿真波形图如图 4-6 所示
图 4-6 功能仿真
4.6 分频模块 JTD_FQU 的设计
本系统提供动态扫描需要的 1kHz 的脉冲,而系统时钟需要 1Hz 的脉冲。分频器主要为系统提供所需的时钟脉冲。该模块将 1kHz 的脉冲进行分频,产生 1S的方波,作为系统时钟信号和特殊情况下的倒计时闪烁信号。其源程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY JTD_FQU IS PORT(
CLK1K:IN STD_LOGIC;
CLK:OUT STD_LOGIC
); END JTD_FQU;
ARCHITECTURE JTD_5 OF JTD_FQU IS SIGNAL Q:STD_LOGIC_VECTOR(9 DOWNTO 0); BEGIN
PROCESS(CLK1K) BEGIN IF(CLK1K"EVENT AND CLK1K="1")THEN Q<=Q+1;
--计数 END IF; END PROCESS; CLK<=Q(9); END JTD_5; 该模块的时序仿真图如图 4-7 所示
推荐访问:信号灯 语言 交通