FPGA交通灯
实验代码如下:
Library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
--//=======================================
entity trafficled is
port(clk1000:IN STD_LOGIC;--时钟1000HZ
res:IN STD_LOGIC;--复位
clk1,clk2:buffer STD_LOGIC;
R1,Y1,G1,R2,Y2,G2:OUT STD_LOGIC;
DEL:buffer STD_LOGIC_VECTOR(2 DOWNTO 0);--位选
led7:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
KEY:IN STD_LOGIC;
D1:buffer STD_LOGIC);
END trafficled;
--//=======================================
architecture behave of trafficled is
signal count_1s:integer range 20 downto 0;--1S计数
signal count:integer ;--1S计数
signal low_digit:integer range 14 downto 0;--数码管显示个位
signal high_digit:integer range 14 downto 0;--ZF存计数值的高位 比比如19S的高位是1
signal CNT_low:integer range 10 downto 0;--数码管显示个位
signal CNT_high:integer range 2 downto 0;
signal ZF:integer range 0 to 4;--方向标志位
signal direction_flag:integer;--// || =
signal temp_d1:STD_LOGIC;
--signal DELq1:STD_LOGIC_VECTOR(2 DOWNTO 0);
signal Disp_Temp:integer range 0 to 14;
begin
--//============分频产生1HZ===============
process(clk1000)
variable count1:integer range 499 downto 0;
variable temp1:STD_LOGIC;
BEGIN
if clk1000 'event and clk1000='1' then
if count1=499 then
temp1:=not temp1;
count1:=0;
else
count1:=count1+1;
end if;
end if;
clk1<=temp1;
end process;
--//===========分频产生2HZ================
process(clk1000)
variable count2:integer range 249 downto 0;
variable temp2:STD_LOGIC;
BEGIN
if clk1000 'event and clk1000='1' then
if count2=249 then
temp2:=not temp2;
count2:=0;
else
count2:=count2+1;
end if;
end if;
clk2<=temp2;
end process;
--//============个位和十位==================lo============================w_digit<=count_1s-10*chigh_digit low_digit<=count_1s;
PROCESS(clk1,res)
--variable low_digit1:integer range 10 downto 0;--数码管显示个位
begin
------------减到0,赋值,换方向----------------------------
if(Clk1'event and Clk1='1') then
count<=count+1;
if count_1s=0 then--00
count_1s<=19;
--low_digit1:=9;
ZF<=ZF+1;
if ZF>4 THEN
ZF<=0; --换方向通车 -----换方向通车
end if;
else
count_1s<=count_1s-1;
--low_digit1:=low_digit1-1;--临时变量,个位数-1
end if;
end if;
---------------------------------------------
IF count<=29 then
if count_1s>9 then
high_digit<=1;--高位为1 逆
low_digit<=count_1s-10;
CNT_high<=0;--顺
CNT_low<=9-low_digit;
elsif count_1s<9 THEN
high_digit<=0;--高位为0
low_digit<=count_1s;
CNT_high<=1;--顺
CNT_low<=9-low_digit;
END IF;
IF KEY='1' THEN
D1<='1';
else
D1<='0';
end if;
temp_d1<=D1;
ELSIF count>29 then
ZF<=4;
high_digit<=14;
low_digit<=14;
D1<=temp_d1;
count<=50;
END IF;
---------------------------------------------
-------------复位 -----------------------------------------
if(res='0') then
low_digit<=9;--20s
high_digit<=1;
--count_1s<=19;
ZF<=0;
END IF;
END PROCESS;
--//=============交通灯==========================
process(clk1,res,count)
begin
if(res='0') then--初始化 复位
R1<='1';R2<='1';--两个红灯亮
G1<='0';G2<='0';
Y1<='0';Y2<='0';
else
if ZF=0 then---向西 -东西绿灯亮15S R1南北红灯亮
if count_1s>=5 then--19-4=15s绿灯
R1<='1';R2<='0';
G1<='0';G2<='1';
Y1<='0';Y2<='0';
else
R1<='1';R2<='0';
G1<='0';G2<='0';
Y1<='0';Y2<=clk2;--东西黄灯闪
end if;
--direction_flag<=10;
elsif ZF=1 then--向南
if count_1s>=5 then--19-4=15s绿灯 --南北绿灯亮15S,,东西红灯亮15S
R1<='0';R2<='1';
G1<='1';G2<='0';
Y1<='0';Y2<='0';
else --东西红灯亮5S
R1<='0';R2<='1';
G1<='0';G2<='0';
Y1<=clk2;Y2<='0';--南北黄灯闪
end if;
--direction_flag<=11;
elsif ZF=2 then---向东 -东西绿灯亮15S R1南北红灯亮
if count_1s>=5 then--19-4=15s绿灯
R1<='1';R2<='0';
G1<='0';G2<='1';
Y1<='0';Y2<='0';
else
R1<='1';R2<='0';
G1<='0';G2<='0';
Y1<='0';Y2<=clk2;--东西黄灯闪
end if;
--direction_flag<=12;
elsif ZF=3 then--向北
if count_1s>=5 then--19-4=15s绿灯 --南北绿灯亮15S,,东西红灯亮15S
R1<='0';R2<='1';
G1<='1';G2<='0';
Y1<='0';Y2<='0';
else --东西红灯亮5S
R1<='0';R2<='1';
G1<='0';G2<='0';
Y1<=clk2;Y2<='0';--南北黄灯闪
end if;
--direction_flag<=13;
elsif ZF=4 then--向北
--if count_1s>=5 then--19-4=15s绿灯 --南北绿灯亮15S,,东西红灯亮15S
R1<='0';R2<='0';
G1<='0';G2<='0';
Y1<=clk2;Y2<=clk2;
end if;
end if;
END PROCESS;
--//=========确定显示方向 东西还是南北====================
process(ZF)
BEGIN
if ZF=0 then
direction_flag<=10;
elsif ZF=1 then--向南
direction_flag<=11;
elsif ZF=2 then---向东
direction_flag<=12;
elsif ZF=3 then--向北
direction_flag<=13;
ELSIF ZF=4 then--向北
direction_flag<=14;
END IF;
END PROCESS;
--//=========1000HZ扫描=======================
PROCESS(clk1000)
begin
if clk1000 'event and clk1000='1' then
DEL<=DEL+1;
END IF;
END PROCESS;
--//=============分配每个数码管的作用====================
process(DEL,high_digit,low_digit,direction_flag,CNT_high,CNT_low)
begin
case (DEL) is
when "000"=>Disp_Temp<=high_digit;--direction_flag;
when "001"=>Disp_Temp<=low_digit;
when "010"=>Disp_Temp<=direction_flag;
when "011"=>Disp_Temp<=direction_flag;
--when others=>Disp_Temp<=0;
when "100"=>Disp_Temp<=high_digit;
when "101"=>Disp_Temp<=low_digit;
when "110"=>Disp_Temp<=direction_flag;
when "111"=>Disp_Temp<=direction_flag;
when others=>null;
end case;
end process;
--//============数码管显示===================
process(DEL,Disp_Temp) --显示转换
begin
case Disp_Temp is
when 0=>led7<="00111111"; --'0'
when 1=>led7<="00000110"; --'1'
when 2=>led7<="01011011"; --'2'
when 3=>led7<="01001111"; --'3'
when 4=>led7<="01100110"; --'4'
when 5=>led7<="01101101"; --'5'
when 6=>led7<="01111101"; --'6'
when 7=>led7<="00000111"; --'7'
when 8=>led7<="01111111"; --'8'
when 9=>led7<="01101111"; --'9'
when 10=>led7<="00100001"; --向西 ,直走和左转 00100001
when 11=>led7<="01110000"; --向东,直走和左转 01000010
when 12=>led7<="01000010"; --向南,直走和左转 01110000
when 13=>led7<="01000110"; --向北,直走和左转 01000110
when 14=>led7<="00000000";
when others=>null; --全灭
end case;
end process;
end architecture behave;