📄 vhdl交通灯0.txt
字号:
引用 基于VHDL的交通灯设计
人工智能论文
一、丁字路口
如图当西方向和南方向绿灯亮时,其他方向亮红灯容许西向左转至南,当东西方向绿灯亮时,南北方向红灯亮容许北向右转至东,当北西方向绿灯时其他方向红灯亮并容许北左转至西。交通灯维持变亮的时间取决于键盘输入的控制键值。总体由状态机实现控制,本设计中使用状态机设有7个状态分别控制东西和南北两个方向的交通,分别对应西南绿灯亮东北红灯亮、南向黄灯亮并闪烁5秒、东西红绿亮南北红灯亮、东黄灯亮、西北绿灯亮东南红灯亮和出现紧急状况时所有方向上的红灯同时变亮。
键盘输入模块控制倒数计数时间以及复位等功能,控制电路模块用来接收键盘产生的倒计数时间分配输出的各个红绿灯的亮灭,实现各种状态的转换,倒计秒数显示倒计时时间,红绿灯显示为最终输出结果。同时键盘有复位功能,交通灯控制具有复位初始状态的功能。数码管显示分为四组,分别用来显示红、绿、黄灯倒计时,状态循环周期,以及键盘输入值显示。
1、键值输入识别程序段
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity KeyIN is
port(
clk:in std_logic;
RL :in std_logic_vector(7 downto 0);
getkey:out std_logic;
keyvalue : buffer std_logic_vector(3 downto 0);
kb0 :buffer std_logic:='0');
end KeyIN;
architecture arch of KeyIN is
FUNCTION coder(RL:std_logic_vector(7 downto 0)) --coder函数,列值译码
RETURN std_logic_vector IS
variable result:std_logic_vector(2 downto 0);
begin
case RL(7 downto 0) is
when "11111110" =>result:="000";
when "11111101" =>result:="001";
when "11111011" =>result:="010";
when "11110111" =>result:="011";
when "11101111" =>result:="100";
when "11011111" =>result:="101";
when "10111111" =>result:="110";
when others =>result:="111";
end case;
RETURN result;
end coder;
signal delay : std_logic :='1';
BEGIN
read:PROCESS(clk)
variable count: integer:=0;
variable keycode:std_logic_vector(3 downto 0);
begin
if(clk'event and clk='1')then --按行扫描,kb0='0'或'1'时,分别扫第0、1行; 默认kb0='0'。
getkey<=delay;
if(RL/="11111111")then --有按键时,列值不为全1
count:=count+1;
if(delay='1')then
if(count=20)then
keycode(3):=kb0;
keycode(2 downto 0):=coder(RL); --调用coder函数
keyvalue<=keycode; --获取键值
delay<='0';
end if;
end if;
else --无按键,换状态,kb0取反
kb0<=not(kb0);
delay<='1';
count:=0;
end if;
end if;
end process read;
end arch;
-------------------------------------------------------------------------------------------------------------------------------------------
引用 基于VHDL的交通灯设计
人工智能论文
2、键值进制转换程序段(转换为10进制)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity CH_KEYIN is
port(
reset,clk:in std_logic;
keyvalue:in std_logic_vector(3 downto 0);
time:out integer range 0 to 99);
end CH_KEYIN;
architecture arch of CH_KEYIN is
signal bl : std_logic :='0';
BEGIN
process(clk,reset)
variable count:integer range 0 to 2 :=0;
variable temp: integer range 0 to 9;
variable timeh,timel:std_logic_vector(3 downto 0);
begin
if reset='0' then
time<=40;
elsif keyvalue="1111" then
bl<='1';
count:=0;
elsif clk'event and clk='1' then
if bl='1' then
if count=0 then
timeh:=keyvalue;
temp := conv_integer(keyvalue);
elsif count=1 then
timel:=keyvalue;
elsif count=2 and keyvalue="1010" then
time <=temp*10 + conv_integer(timel);
bl<='0';
count:=0;
end if;
count:=count+1;
end if;
end if;
end process;
END arch;
3、交通灯控制程序段
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY jtdcontrler IS
PORT (clk,reset,RRR: IN STD_LOGIC;
Timein:in integer range 0 to 99;
mr,mg,sr,sg,wr,wg : OUT STD_LOGIC ; --,showbt
showbt : OUT STD_LOGIC_VECTOR (2 DOWNTO 0); --显示位控制
mmy,ssy,wwy : BUFFER STD_LOGIC;
show : OUT STD_LOGIC_VECTOR (6 DOWNTO 0)
); --show : OUT STD_LOGIC_VECTOR (6 DOWNTO 0)
END jtdcontrler ;
ARCHITECTURE one OF jtdcontrler IS
TYPE state_type IS (A,B,C,D,E,F,G);
SIGNAL state : state_type;
SIGNAL secclk,yellowsec,my,sy,wy : STD_LOGIC;
SIGNAL showclk : STD_LOGIC_VECTOR (2 DOWNTO 0); --后加,LED显示时钟
SIGNAL showdata1,showdata0 : INTEGER RANGE 0 TO 99;
SIGNAL datasignal : INTEGER RANGE 0 TO 9;
BEGIN
getclk: PROCESS ( clk )
VARIABLE clkcount : INTEGER RANGE 0 TO 2; --LED位扫描信号
VARIABLE sclk : INTEGER RANGE 0 TO 600; --秒信号
VARIABLE yellowcou : INTEGER RANGE 0 TO 200; --黄灯闪烁信号
BEGIN
IF clk'EVENT AND clk = '1' THEN
clkcount := clkcount + 1;
sclk := sclk + 1;
yellowcou := yellowcou + 1;
IF clkcount = 3 THEN
showclk <= showclk + '1';
END IF;
IF sclk = 600 THEN
secclk <= '1';
ELSE secclk <= '0';
END IF;
IF yellowcou = 200 THEN
yellowsec <= '1';
ELSE yellowsec <= '0';
END IF;
END IF;
END PROCESS getclk;
jtdp: PROCESS (secclk,reset,rrr)
VARIABLE cnt : INTEGER RANGE 0 TO 99;
VARIABLE nclr : BIT; --nclr低电平计数器清零
BEGIN
IF ( secclk'EVENT AND secclk = '1' ) THEN
IF nclr = '0' THEN cnt := 0; --同步清零
ELSE cnt := cnt + 1; --如果nclr不等于零,则计数
END IF;
--END IF;记住
------------------------------------------------------------------------------------------------------------------------------
CASE state IS
WHEN A => mr <= '0'; my <= '0'; mg <= '1'; --A状态,东西绿灯mg亮
sr <= '1'; sy <= '0'; sg <= '0'; wr <='1';wy <='0';wg <='0';
showdata1 <= timein - cnt; showdata0 <= (timein+5) -cnt;
IF cnt = timein THEN
state <= B; nclr := '0';cnt := 0;
ELSE state <= A; nclr := '1'; --继续状态A
END IF;
WHEN B => mr <= '0'; my <= '1'; mg <= '0'; --B状态,东西黄灯my亮
sr <= '1'; sy <= '0'; sg <= '0';wr <='1';wy <='0';wg <='0';
showdata1 <= 5 - cnt; showdata0 <=5 - cnt;
IF cnt = 5 THEN
state <= C; nclr := '0';
ELSE state <= B; nclr := '1';
END IF;
WHEN C => mr <= '1'; my <= '0'; mg <= '0'; --C状态,南北绿灯sg亮
sr <= '0'; sy <= '0'; sg <= '1';wr <='1';wy <='0';wg <='0';
showdata1 <= (timein+5) - cnt; showdata0 <= timein - cnt;
IF cnt = timein THEN
state <= D; nclr := '0';cnt := 0;
ELSE state <= C; nclr := '1';
END IF;
WHEN D => mr <= '1'; my <= '0'; mg <= '0'; --D状态,南北黄灯sy亮
sr <= '0'; sy <= '1'; sg <= '0';wr <='1';wy <='0';wg <='0';
showdata1 <= 5 - cnt; showdata0 <= 5 - cnt;
IF cnt = 5 THEN
state <= E; nclr := '0';
ELSE
state <= D; nclr := '1';
END IF;
WHEN E => mr <= '1'; my <= '0'; mg <= '0'; --E状态,之路绿灯wg亮
sr <= '1'; sy <= '0'; sg <= '0';wr <='0';wy <='0';wg <='1';
showdata1 <= (timein+5) - cnt; showdata0 <= timein - cnt;
IF cnt = timein THEN
state <= F; nclr := '0';cnt := 0;
ELSE
state <= E; nclr := '1';
END IF;
WHEN F => mr <= '1'; my <= '0'; mg <= '0'; --E状态,之路黄灯wy亮
sr <= '1'; sy <= '0'; sg <= '0';wr <='0';wy <='1';wg <='0';
showdata1 <= 5 - cnt; showdata0 <= 5 - cnt;
IF cnt = 5 THEN
state <= A; nclr := '0';
ELSE
state <= F; nclr := '1';
END IF;
WHEN G => mr <= '1'; my <= '0'; mg <= '0'; --G状态 紧急情况所有红灯亮
sr <= '1'; sy <= '0'; sg <= '0';wr <='1';wy <='0';wg <='0';
showdata1 <= 0; showdata0 <= 0;
IF cnt = 50 then
state <= A; nclr := '0';
ELSE state <= g; nclr := '1'; --继续状态G
END IF;
END CASE;
IF (reset='0') then
state <= A;nclr := '0';
END IF;
IF (RRR='0') then
state <= G ;nclr :='0';
END IF;
END IF;
END PROCESS jtdp;
showp1: PROCESS ( showclk )
VARIABLE data1,data0,data2,data3,data4,data5,data6,data7 : INTEGER RANGE 0 TO 9;
VARIABLE S : integer range 0 to 99;
BEGIN
S:=timein+timein+10;
IF showdata1 >= 90 THEN --主路计数显示
data1 := 9; data0 := showdata1 - 90;
ELSIF showdata1 >= 80 THEN
data1 := 8; data0 := showdata1 - 80;
ELSIF showdata1 >= 70 THEN
data1 := 7; data0 := showdata1 - 70;
ELSIF showdata1 >= 60 THEN
data1 := 6; data0 := showdata1 - 60;
ELSIF showdata1 >= 50 THEN
data1 := 5; data0 := showdata1 - 50;
ELSIF showdata1 >= 40 THEN
data1 := 4; data0 := showdata1 - 40;
ELSIF showdata1 >= 30 THEN
data1 := 3; data0 := showdata1 - 30;
ELSIF showdata1 >= 20 THEN
data1 := 2; data0 := showdata1 - 20;
ELSIF showdata1 >= 10 THEN
data1 := 1; data0 := showdata1 - 10;
ELSE data1 := 0; data0 := showdata1;
END IF;
IF showdata0 >= 90 THEN --辅路计数显示
data3 := 9; data2 := showdata0 - 90;
ELSIF showdata0 >= 80 THEN
data3 := 8; data2 := showdata0 - 80;
ELSIF showdata0 >= 70 THEN
data3 := 7; data2 := showdata0 - 70;
ELSIF showdata0 >= 60 THEN
data3 := 6; data2 := showdata0 - 60;
ELSIF showdata0 >= 50 THEN
data3 := 5; data2 := showdata0 - 50;
ELSIF showdata0 >= 40 THEN
data3 := 4; data2 := showdata0 - 40;
ELSIF showdata0 >= 30 THEN
data3 := 3; data2 := showdata0 - 30;
ELSIF showdata0 >= 20 THEN
data3 := 2; data2 := showdata0 - 20;
ELSIF showdata0 >= 10 THEN
data3 := 1; data2 := showdata0 - 10;
ELSE data3 := 0; data2 := showdata0;
END IF;
IF timein >= 90 THEN --辅路计数显示
data5 := 9; data4 := timein - 90;
ELSIF timein >= 80 THEN
data5 := 8; data4 := timein - 80;
ELSIF timein >= 70 THEN
data5 := 7; data4 := timein - 70;
ELSIF timein >= 60 THEN
data5 := 6; data4 := timein - 60;
ELSIF timein >= 50 THEN
data5 := 5; data4 := timein - 50;
ELSIF timein >= 40 THEN
data5 := 4; data4 := timein - 40;
ELSIF timein >= 30 THEN
data5 := 3; data4 := timein - 30;
ELSIF timein >= 20 THEN
data5 := 2; data4 := timein - 20;
ELSIF timein >= 10 THEN
data5 := 1; data4 := timein - 10;
ELSE data5 := 0; data4 := timein ;
END IF;
IF s >= 90 THEN -- 循环周期显示
data7 := 9; data6 := s - 90;
ELSIF s >= 80 THEN
data7 := 8; data6 := s - 80;
ELSIF s >= 70 THEN
data7 := 7; data6 := s - 70;
ELSIF s >= 60 THEN
data7 := 6; data6 := s - 60;
ELSIF s >= 50 THEN
data7 := 5; data6 := s - 50;
ELSIF s >= 40 THEN
data7 := 4; data6 := s - 40;
ELSIF s >= 30 THEN
data7 := 3; data6 := s - 30;
ELSIF s >= 20 THEN
data7 := 2; data6 := s - 20;
ELSIF s >= 10 THEN
data7 := 1; data6 := s - 10;
ELSE data7 := 0; data6 := s ;
END IF;
CASE showclk IS
WHEN "000" => showbt <= "000"; datasignal <= data3;
WHEN "001" => showbt <= "001"; datasignal <= data2;
WHEN "010" => showbt <= "010"; datasignal <= data1;
WHEN "011" => showbt <= "011"; datasignal <= data0;
WHEN "100" => showbt <= "100"; datasignal <= data7;
WHEN "101" => showbt <= "101"; datasignal <= data6;
WHEN "110" => showbt <= "110"; datasignal <= data5;
WHEN "111" => showbt <= "111"; datasignal <= data4;
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
showp2: PROCESS ( datasignal )
BEGIN
CASE datasignal IS
WHEN 0 => show <= "0111111";
WHEN 1 => show <= "0000110";
WHEN 2 => show <= "1011011";
WHEN 3 => show <= "1001111";
WHEN 4 => show <= "1100110";
WHEN 5 => show <= "1101101";
WHEN 6 => show <= "1111101";
WHEN 7 => show <= "0000111";
WHEN 8 => show <= "1111111";
WHEN 9 => show <= "1101111";
WHEN OTHERS => NULL;
END CASE;
END PROCESS showp2;
yellow: PROCESS (yellowsec)
BEGIN
IF yellowsec'EVENT AND yellowsec ='1' THEN
IF my = '1' THEN
mmy <= not mmy;
END IF;
IF sy = '1' THEN
ssy <= not ssy;
END IF;
IF wy ='1' THEN
wwy <= not wwy;
END IF;
END IF;
END PROCESS;
END one;
上一页 [1] [2] [3] [4] 下一页
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -