数电实验
-
问题描述(功能要求):
T型路口交通信号灯的工作过程,利用实验板上的 红、黄、绿LED作为交通信号灯,设计一个交通信号灯控制器。要求:
(1) 交通灯从绿变红时,有5秒黄灯亮的间隔时间;
(2) 交通灯红变绿是直接进行的,没有间隔时间;
(3) 南北主干道上的绿灯时间为45秒,东西支干道的绿灯时间为25秒;
(4) 在任意时间,显示每个状态到该状态结束所需的时间。 -
运行环境要求:
硬件环境:DDA-IIIA学习板
软件环境:Quartus II
T型路口的交通信号灯,信号灯由黄红绿三色组成,南到北 运行时,绿灯亮45秒钟,45秒后,黄灯亮5秒,东方向到北方向为红灯,且南北道和北南道的左转和右转灯不亮.5秒后,南北道和北南道的红灯亮,东西道的绿灯亮,且南北道和北南道的左转和右转灯都亮,25秒后,东西道的亮黄灯,且南北道和北南道的左转和右转灯的灯亮,5秒钟后, 东西道的亮红灯,且南北道和北南道的左转和右转灯的灯不亮,所有的出现的时间显示在数码管上面,即每个灯亮的时显示相应的秒数并计时.
**设定实体**
定义
Clk:时钟信号
resert--复位信号;
clk1 --显示时钟
right1 --南到北右转进入支通道
red1--南到北红灯
yellow1--南到北黄灯
green1--南到北绿灯
red2 --东到西红灯
yellow2 –东到西黄灯
green2--东到西绿灯
red3 –北到南红灯
yellow3—北到南黄灯
green3 – 北到南绿灯
left3--北到南左转
sel :out std_logic_vector(6 downto 0 );数码管段选显示
times:out std_logic_vector(7 downto 0);数码管位选选择
在
signal times1: integer range 0 to 9; --从北到南直行灯的十位时间
signal times2: integer range 0 to 9;–从北到南直行的灯个位时间
signal times3: integer range 0 to 9;–从南到北直行的灯的十位时间
signal times4: integer range 0 to 9;–从南到北直行的灯的个位时间
signal times5: integer range 0 to 9; --从东右转,从南到北右转,从北到南左转的十位时间
signal times6: integer range 0 to 9; --从东右转,从南到北右转,从北到南左转的个位时间
pin脚分配
输入/输出 变量 名称 Pin 按键位置
输入 CLK 初始时钟 PIN_91 CLK4
CLK2 显示时钟 PIN_89 CLK2
reset 紧急信号 PIN_60 A0
输出 Sel[6] 时间显示 PIN_133 数码管 A
Sel[5] PIN_134 B
Sel[4] PIN_135 C
Sel[3] PIN_136 D
Sel[2] PIN_137 E
Sel[1] PIN_139 F
Sel[0] PIN_141 G
times[7] 数码管显示地址选择 PIN_132 SEL7
times[6] PIN_129 SEL6
times[5] PIN_126 SEL5
times[4] PIN_125 SEL4
times[3] PIN_122 SEL3
times[2] PIN_121 SEL2
times[1] PIN_120 SEL1
times[0] PIN_119 SEL0
green1 南到北绿灯 PIN_115
Green2 东到西道的红灯 Pin_100
Green3 北到南的绿灯 PIN_86
Red1 南到北的红灯 Pin_114
Red2 东到西的红灯 Pin_99
Red3 北到南的绿灯 Pin_81
yellow1 南到北黄灯 Pin_113
Yellow2 东到西黄灯 Pin_97
Yellow3 北到南黄灯 Pin_80
left3 北到南左转 Pin_97
right1 南到北向东右转 Pin_112
程序清单
-
library ieee; use ieee.std_logic_1164.all; use
ieee.std_logic_unsigned.all; entity traffic_light is port(clk:in
std_logic;–时钟信号输入端,预设周期1秒 resert:in std_logic;–复位信号; clk1:in
std_logic; --显示时钟
right1, red1,yellow1,green1:out std_logic;–南->北右转、红、黄、绿5灯控制信号输出端
red2,yellow2,green2:out std_logic;–东>西 右转、红、黄、绿5灯控制信号输出端 red3,yellow3,green3,left3:out std_logic;–北到南红绿黄,左转
–次干道左转、右转、红、黄、绿5灯控制信号输出端 sel :out std_logic_vector(6 downto 0 ); times:out std_logic_vector(7 downto 0)); end traffic_light;
architecture bhv of traffic_light is signal full : std_logic; signal
times1: integer range 0 to 9; signal times2: integer range 0 to
9;–从北到南直行以及从北左转的灯的时间 signal times3: integer range 0 to 9; signal
times4: integer range 0 to 9;–从南到北直行的灯的时间 signal times5: integer
range 0 to 9; signal times6: integer range 0 to 9;–从东左转的灯的时间
signal num : std_logic_vector(2 downto 0); begin p1:process(clk)
variable cont1 : integer range 100 downto 0; begin
if(clk’event and clk=‘1’ and resert = ‘0’)then
if(cont1=99)then
cont1:=0;full<=‘1’;
else cont1:=cont1+1;full<=‘0’;
end if; end if; end process p1; p3:process(full) variable time : integer range 0 to 100; begin if(resert = ‘1’)then
–如果暂停为1,全部为红灯,数码管上的数字暂停 right1<=‘0’;red1<=‘1’;yellow1<=‘0’;green1<=‘0’;
red2<=‘1’;yellow2<=‘0’;green2<=‘0’;
left3<=‘0’;red3<=‘1’;yellow3<=‘0’;green3<=‘0’; else if(full’event and full='1’and resert = ‘0’)then --按频率时间递减
if(time=0)then
time:=80;
else
–当各位为零时十位减一,否则各位自减一
time:=time-1;
if(times2 = 0)then
times1 <= times1-1;
times2 <= 9;
else
times2 <= times2-1;
end if;
if(times4 = 0)then
times3 <= times3-1;
times4 <= 9;
else
times4 <= times4-1;
end if;
if(times6 = 0)then
times5 <= times5-1;
times6 <= 9;
else
times6 <= times6-1;
end if;
end if; if time<80 and time >34 then right1<=‘0’;red1<=‘0’;yellow1<=‘0’;green1<=‘1’;
red2<=‘1’;yellow2<=‘0’;green2<=‘0’;
left3<=‘0’;red3<=‘0’;yellow3<=‘0’;green3<=‘1’;–两条主干道绿灯45秒,次方向红灯,转弯灯不亮,
各个时间改变 if time= 79 then
times1 <= 4;
times2 <= 5;
times3 <= 4;
times4 <= 5;
times5 <= 5;
times6 <= 0; end if;
end if; if time>29 and time<35 then –-两条主干道变黄灯,次干道还是黄灯,转弯灯不亮, 各个时间改变 right1<=‘0’;red1<=‘0’;yellow1<=‘1’;green1<=‘0’;
red2<=‘1’;yellow2<=‘0’;green2<=‘0’;
left3<=‘0’;red3<=‘0’;yellow3<=‘1’;green3<=‘0’; if(time=34)then
times1 <= 0; times2 <= 5; times3 <= 0; times4 <= 5;
end if; end if; if time>4 and time< 30 then
–-两条主干道变红灯,次干道为绿灯,转弯灯亮,各个时间改变
right1<=‘1’;red1<=‘0’;yellow1<=‘0’;green1<=‘0’;
red2<=‘0’;yellow2<=‘0’;green2<=‘1’;
left3<=‘1’;red3<=‘0’;yellow3<=‘0’;green3<=‘0’;
if(time=29)then times1 <= 3; times2 <= 0; times3 <= 3; times4 <= 0; times5 <= 2; times6 <= 5; end if;
end if; if time<5 then –-两条主干道变红灯,次干道为黄灯,转弯灯亮 各个时间改变 right1<=‘1’;red1<=‘0’;yellow1<=‘0’;green1<=‘0’;
red2<=‘0’;yellow2<=‘1’;green2<=‘0’;
left3<=‘1’;red3<=‘0’;yellow3<=‘0’;green3<=‘0’;–次干道黄4秒1 times5<=0; times6<= 5; end if; end if; end if; end
process;–结束进程TIMEOUT: process(clk1,times6,times5,times4,times3,times2,times1) --显示模块
variable smg7:std_logic_vector(6 downto 0);
VARIABLE num:integer range 0 to 5;–设定变量num,通过num的自加1用于后面的位选选择
begin
if(clk1’event and clk1=‘1’)then
–case语句来选择段和位选,当num = 0,1,2,3,4,5时,选择不同的语句进行,
case num is when 0=>
case times6 isWHEN 0 => smg7:="1111110"; --显示数字0 WHEN 1 => smg7:="0110000"; --显示数字1 WHEN 2 => smg7:="1101101"; --显示数字2 WHEN 3 => smg7:="1111001"; --显示数字3 WHEN 4 => smg7:="0110011"; --显示数字4 WHEN 5 => smg7:="1011011"; --显示数字5 WHEN 6 => smg7:="1011111"; --显示数字6 WHEN 7 => smg7:="1110000"; --显示数字7 WHEN 8 => smg7:="1111111"; --显示数字8 WHEN 9 => smg7:="1111011"; --显示数字9 end case; times<="11111110";--位选 sel<=smg7;--将获得的数字给sel段选信号 when 1=> case times5 is WHEN 0 => smg7:="1111110"; --显示数字0 WHEN 1 => smg7:="0110000"; --显示数字1 WHEN 2 => smg7:="1101101"; --显示数字2 WHEN 3 => smg7:="1111001"; --显示数字3 WHEN 4 => smg7:="0110011"; --显示数字4 WHEN 5 => smg7:="1011011"; --显示数字5 WHEN 6 => smg7:="1011111"; --显示数字6 WHEN 7 => smg7:="1110000"; --显示数字7 WHEN 8 => smg7:="1111111"; --显示数字8 WHEN 9 => smg7:="1111011"; --显示数字9 end case; times<="11111101";--位选 sel<=smg7; --将获得的数字给sel段选信号 when 2=> case times4 is WHEN 0 => smg7:="1111110"; --显示数字0 WHEN 1 => smg7:="0110000"; --显示数字1 WHEN 2 => smg7:="1101101"; --显示数字2 WHEN 3 => smg7:="1111001"; --显示数字3 WHEN 4 => smg7:="0110011"; --显示数字4 WHEN 5 => smg7:="1011011"; --显示数字5 WHEN 6 => smg7:="1011111"; --显示数字6 WHEN 7 => smg7:="1110000"; --显示数字7 WHEN 8 => smg7:="1111111"; --显示数字8 WHEN 9 => smg7:="1111011"; --显示数字9 end case; times<="11111011";--位选 sel<=smg7; --将获得的数字给sel段选信号 when 3=> case times3 is WHEN 0 => smg7:="1111110"; --显示数字0 WHEN 1 => smg7:="0110000"; --显示数字1 WHEN 2 => smg7:="1101101"; --显示数字2 WHEN 3 => smg7:="1111001"; --显示数字3 WHEN 4 => smg7:="0110011"; --显示数字4 WHEN 5 => smg7:="1011011"; --显示数字5 WHEN 6 => smg7:="1011111"; --显示数字6 WHEN 7 => smg7:="1110000"; --显示数字7 WHEN 8 => smg7:="1111111"; --显示数字8 WHEN 9 => smg7:="1111011"; --显示数字9 end case; times<="11110111";--位选 sel<=smg7; --将获得的数字给sel段选信号 when 4=> case times2 is WHEN 0 => smg7:="1111110"; --显示数字0 WHEN 1 => smg7:="0110000"; --显示数字1 WHEN 2 => smg7:="1101101"; --显示数字2 WHEN 3 => smg7:="1111001"; --显示数字3 WHEN 4 => smg7:="0110011"; --显示数字4 WHEN 5 => smg7:="1011011"; --显示数字5 WHEN 6 => smg7:="1011111"; --显示数字6 WHEN 7 => smg7:="1110000"; --显示数字7 WHEN 8 => smg7:="1111111"; --显示数字8 WHEN 9 => smg7:="1111011"; --显示数字9 end case; times<="11101111";--位选 sel<=smg7; --将获得的数字给sel段选信号 when 5=> case times1 is WHEN 0 => smg7:="1111110"; --显示数字0 WHEN 1 => smg7:="0110000"; --显示数字1 WHEN 2 => smg7:="1101101"; --显示数字2 WHEN 3 => smg7:="1111001"; --显示数字3 WHEN 4 => smg7:="0110011"; --显示数字4 WHEN 5 => smg7:="1011011"; --显示数字5 WHEN 6 => smg7:="1011111"; --显示数字6 WHEN 7 => smg7:="1110000"; --显示数字7 WHEN 8 => smg7:="1111111"; --显示数字8 WHEN 9 => smg7:="1111011"; --显示数字9 end case; times<="11011111";--位选 sel<=smg7; --将获得的数字给sel段选信号 end case; num := num+1; end if; end process;--结束进程
end bhv; --结束这个程序
上面的显示模块可以使用函数写出来,这样可以节省很多代码,在状态选择进程中可以在前面定义一个枚举设定为S0-s3,因为我的只有四个状态,枚举中写你的状态代表变量就行了