1、交通灯控制器设计
状态转换图:
各个状态的时间:
数码管显示原理图:
程序的模块分类:
源代码:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_unsigned.all;
USE IEEE.STD_LOGIC_ARITH.ALL;
--io define--
entity traffic_Light is
port(
sysclk : in STD_LOGIC; --ipput->system clock
reset : in STD_LOGIC; --reset signal -> 0 to reset ,1 :normal
enable : in STD_LOGIC; --enable signal -> 1 to enable,0 to disable
led : out std_logic_vector ( 5 downto 0); --ledcontrol
DIG_S,SEG : out std_logic_vector(7 downto 0) --seg,bitselect and segselect
);
end traffic_Light;
architecture rtl of traffic_Light is
signal clk : std_logic; --1khz 0.001s
signal clk1 : std_logic; --1hz 1s
signal cnt : std_logic_vector ( 15 downto 0); --counter 16bit
signal cnt1 : std_logic_vector ( 11 downto 0); --counter 1 12bit
signal count : std_logic_vector ( 1 downto 0);
signal i:integer:=0; --creat a interger varibale i and init 0
signal abshi,abge,cdshi,cdge:integer; --ab oriential time,include shi ge
signal abshi1,abge1,cdshi1,cdge1:std_logic_vector (7 downto 0); --control IO
type state_type is (s0, s1, s2, s3); --define the all of states
signal state : state_type:=s0; --init statas is s0
signal y_ab,r_ab,g_cd,y_cd:INTEGER RANGE 0 TO 35; --
signal g_ab:INTEGER:=30; --intial ab oriental green_lignt is 30 seconds
signal r_cd:INTEGER:=35; --intial cd oriental red_light is 35 seconds
begin
----div the system clock module--
process( sysclk ,reset ) --process sentiment is sysclk and reset
begin
if reset='0' then
cnt <= "0000000000000000"; --reset enable ,initial the cnt
clk <= '1';
elsif ( sysclk'event and sysclk = '1') then --if system rise edge
cnt <= cnt + 1; --cnt++
if (cnt = "0000000000001101") then--0110000110101000=25000 50000 is a cycle
--0000000000000101=5 5Mhz = 0.0000002s
cnt <= "0000000000000000";
clk <= NOT clk ; -- 25000 times invert the clk
end if ;
end if;
end process ;
--div the clk -- > clk1 --
--the clk is 1k Hz 0.001s,--
--create clk1 1 the frequency is 1s --
process (clk ,reset)
begin
if reset='0' then
cnt1 <= "000000000000";
clk1 <= '0';
elsif ( clk'event and clk = '1') then -- 1khz 0.001s extcute
-- 50Mhz 0.0000002s extcute ,
cnt1 <= cnt1 + 1;
if (cnt1 = "0101") then--000111110100=500 1k->0.5s 5M->0.0001s=0.1ms
cnt1 <= "000000000000" ; --one cycle is Tclk * 500*2
--5MHz cycle = 0.0000002 *1000 = 0.0002s = 0.2ms
clk1 <= NOT clk1 ; --the clk cycle is 1s
end if ;
end if;
end process ;
--the clk1 is 1s-- need 70 one cycle = 0.2 * 70 = 14 ms
process (clk1, reset)
begin
if reset = '0' then
state <= s0;g_ab<=30;r_cd<=35; --this is a reset process
elsif (clk1='1' AND clk1'EVENT ) then --respond clk rise edge
if enable = '1' then --makesure enable,vaild is 1
case state is
when s0=> --the first process
if g_ab=0 then --ab oriental green_light On
state <= s1;y_ab<=4;abshi<=0;abge<=5;
else
--g_ab will deduct 1
state <= s0;g_ab<=g_ab-1;
--seg display--ab oriental including ge shi
abshi<=g_ab/10;abge<=g_ab rem 10;
end if;
r_cd<=r_cd-1;cdshi<=r_cd/10;cdge<=r_cd rem 10;
when s1=>
if y_ab=0 then --if y_ab duduct to 0,yellow_light timeout
state <= s2; --enter satate s2
r_ab<=34;g_cd<=29; --initial the ab oriental value
abshi<=3;abge<=5; --initial the seg display
cdshi<=3;cdge<=0;
else
state <= s1; --enter state s1
y_ab<=y_ab-1; --sub y_ab
abshi<=y_ab/10;abge<=y_ab rem 10; --refresh ab seg
r_cd<=r_cd-1;cdshi<=r_cd/10;cdge<=r_cd rem 10; --refresh cd seg
end if;
when s2=>
if g_cd=0 then
state <= s3;y_cd<=4;cdshi<=0;cdge<=5;
else
state <= s2;g_cd<=g_cd-1;cdshi<=g_cd/10;cdge<=g_cd rem 10;
end if;
r_ab<=r_ab-1;abshi<=r_ab/10;abge<=r_ab rem 10;
when s3 =>
if y_cd=0 then
state <= s0;g_ab<=29;r_cd<=34;cdshi<=3;cdge<=5;abshi<=3;abge<=0;
else
state <= s3;y_cd<=y_cd-1;cdshi<=y_cd/10;cdge<=y_cd rem 10;r_ab<=r_ab-1;abshi<=r_ab/10;abge<=r_ab rem 10;
end if;
end case;
end if;
end if;
end process;
process (state)
begin
case state is
when s0 =>
led <= "011110";--100001
when s1 =>
led <= "101110";--010001
when s2 =>
led <= "110011";--001100
when s3 =>
led <= "110101";--001010
end case;
if (abshi=0) then
if abge<=3 then
if clk1 = '0' then
led(5)<='1';led(4)<='1';led(3)<='1';
end if;
end if;
end if;
if (cdshi=0) then
if cdge<=3 then
if clk1 = '0' then
led(2)<='1';led(1)<='1';led(0)<='1';
end if;
end if;
end if;
end process;
--seg display--
--the proces is conver the interget to vector for the purpose of controling the IO
process(cdge,cdshi,abge,abshi)
begin
case cdge is
when 0 => cdge1<="11000000";--00111111
when 1 => cdge1<="11111001";--00000110
when 2 => cdge1<="10100100";--01001011
when 3 => cdge1<="10110000";--01001111
when 4 => cdge1<="10011001";--01100110
when 5 => cdge1<="10010010";--01101101
when 6 => cdge1<="10000011";--01111100
when 7 => cdge1<="11011000";--00100111
when 8 => cdge1<="10000000";--01111111
when 9 => cdge1<="10011000";--01100111
when others => cdge1<="11111111";
end case;
case cdshi is
when 0 => cdshi1<="11000000";--00111111
when 1 => cdshi1<="11111001";--00000110
when 2 => cdshi1<="10100100";--01001011
when 3 => cdshi1<="10110000";--01001111
when 4 => cdshi1<="10011001";--01100110
when 5 => cdshi1<="10010010";--01101101
when 6 => cdshi1<="10000011";--01111100
when 7 => cdshi1<="11011000";--00100111
when 8 => cdshi1<="10000000";--01111111
when 9 => cdshi1<="10011000";--01100111
when others => cdshi1<="11111111";
end case;
case abge is
when 0 => abge1<="11000000";--00111111
when 1 => abge1<="11111001";--00000110
when 2 => abge1<="10100100";--01001011
when 3 => abge1<="10110000";--01001111
when 4 => abge1<="10011001";--01100110
when 5 => abge1<="10010010";--01101101
when 6 => abge1<="10000011";--01111100
when 7 => abge1<="11011000";--00100111
when 8 => abge1<="10000000";--01111111
when 9 => abge1<="10011000";--01100111
when others => abge1<="11111111";
end case;
case abshi is
when 0 => abshi1<="11000000";--00111111
when 1 => abshi1<="11111001";--00000110
when 2 => abshi1<="10100100";--01001011
when 3 => abshi1<="10110000";--01001111
when 4 => abshi1<="10011001";--01100110
when 5 => abshi1<="10010010";--01101101
when 6 => abshi1<="10000011";--01111100
when 7 => abshi1<="11011000";--00100111
when 8 => abshi1<="10000000";--01111111
when 9 => abshi1<="10011000";--01100111
when others => abshi1<="11111111";
end case;
end process;
--resfresh the seg--
--every 0.001 s excute--
process(clk,i)
begin
if clk'event and clk='1' then
DIG_S<="11111111"; --this is bit select,close all of seg
DIG_S(i)<='0';
case (i) is
when 0 => SEG<= cdge1;
when 1 => SEG<= cdshi1;
when 2 => SEG<="11111111";
when 3 => SEG<="11111111";
when 4 => SEG<= abge1;
when 5 => SEG<= abshi1;
when 6 => SEG<="11111111";
when 7 => SEG<="11111111";
when others => SEG<="11111111";
end case;
i<=i+1;
if i=8 then i<=0;end if;
end if;
end process;
end rtl;
全部源代码下载:https://download.csdn.net/download/qq_36243942/11133915
扫描二维码关注公众号,回复:
8838474 查看本文章