一、设计任务
设计一个八路彩灯控制器,要求:
1、彩灯明暗变化节拍为0.25S和0.5S两种节拍,采用按键进行频率切换。2、演示花型3种,分别为左移、右移、闪烁。每种花型显示时间维持20秒,显示花型种类号和倒计时。
3、彩灯用发光二极管LED模拟。
二、任务分析
1、该系统的外加信号为时钟,输出为多路彩灯信号。彩灯控制器按一定的节拍改变8路输出的高低电平,控制彩灯按预定的规律亮灭,从而显示一定的花型。根据设计任务,彩灯控制器应包含时钟电路编码器和控制电路。时钟可以采用全局时钟分频后时钟输出信号;编码器根据花型要求按节拍产生8位输出编码信号,控制彩灯按规律亮灭;控制电路则应控制编码器的节拍脉冲和3种花形的循环切换,同步整个系统工作。
2、0.25S和0.5S秒信号由时钟分频获得。
3、循环显示方式自定:可以按照左移-闪烁-右移-左移方式显示,也可以按照其他方式显示。
4、可以选择1HZ 时钟脉冲作为系统时钟。
5、0.25S 和 0.5S 秒信号可以由时钟分频获得。
6、循环显示方式自定:可以按照左移-闪烁-右移-左移方式显示,也可以按照其他方式显示
三、整体电路图
四、各模块VHDL程序
- 任意整数分频模块程序
--//********任意整数分频模块********//
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.NUMERIC_BIT.ALL;--包含移位函数等.
ENTITY int_div IS
GENERIC( F_DIV:Integer:=48000000;--分频系数
F_DIV_WIDTH:Integer:=32--分频计数器宽度
);
PORT(clock : IN STD_LOGIC;
clock_out: OUT STD_LOGIC);
END;
ARCHITECTURE one OF int_div IS
SIGNAL clk_p_r: STD_LOGIC;--上升沿输出时钟
SIGNAL clk_n_r: STD_LOGIC;--下降沿输出时钟
SIGNAL count_p: STD_LOGIC_VECTOR(f_div_width-1 DOWNTO 0);--上升沿脉冲计数器
SIGNAL count_n: STD_LOGIC_VECTOR(f_div_width-1 DOWNTO 0);--下降沿脉冲计数器
SIGNAL clock_out_r:STD_LOGIC;
SIGNAL full_div_p: STD_LOGIC;--上升沿计数满标志
SIGNAL half_div_p: STD_LOGIC;--上升沿计数半满标志
SIGNAL full_div_n: STD_LOGIC;--下降沿计数满标志
SIGNAL half_div_n: STD_LOGIC;--下降沿计数半满标志
BEGIN
clock_out<=clock_out_r;
--clock_out<=clock WHEN (F_DIV=1) ELSE ((clk_p_r='1' AND clk_n_r='1') WHEN (F_DIV(0)='1') clk_p_r);
-------------------------<<判断计数标志位置位与否.
full_div_p<='1' WHEN (count_p<F_DIV-1) ELSE '0';
half_div_p<='1' WHEN (count_p<(F_DIV/2 )-1) ELSE '0';
full_div_n<='1' WHEN (count_n<F_DIV -1) ELSE '0';
half_div_n<='1' WHEN (count_n<(F_DIV/2)-1) ELSE '0';
PROCESS(clock)--上升沿脉冲计数
--VARIABLE i:Integer RANGE 0 TO 31;
BEGIN
IF RISING_EDGE(clock)THEN
IF full_div_p='1' THEN
count_p<=count_p+1;
IF (half_div_p='1') THEN
clk_p_r<='0';
ELSE
clk_p_r<='1';
END IF;
ELSE
count_p<= (OTHERS =>'0');
clk_p_r<= '0';
END IF;
END IF;
END PROCESS;
PROCESS(clock)--下降沿脉冲计数
BEGIN
IF FALLING_EDGE(clock)THEN
IF full_div_n='1' THEN
count_n<=count_n+1;
IF half_div_n='1' THEN
clk_n_r<='0';
ELSE
clk_n_r<='1';
END IF;
ELSE
count_n<=(OTHERS =>'0');
clk_n_r <= '0';
END IF;
END IF;
END PROCESS;
PROCESS(clock)
BEGIN
IF RISING_EDGE(clock)THEN
IF F_DIV= 1 THEN
clock_out_r<=clock;
ELSE
IF (F_DIV REM 2) =1 THEN
clock_out_r<= clk_p_r AND clk_n_r;
ELSE
clock_out_r<=clk_p_r;
END IF;
END IF;
END IF;
END PROCESS;
END;
- 二选一模块程序
--//********二选一模块********//
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mux21 IS
PORT(a,b,s: IN STD_LOGIC;
y: OUT STD_LOGIC);
END mux21;
ARCHITECTURE ar OF mux21 IS
BEGIN
PROCESS(a,b,s)
BEGIN
IF s='0' THEN
y<=a;
ELSE
y<=b;
END IF;
END PROCESS;
END ar;
- 20计数器模块程序
--//********20计数器模块********//
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT20 IS
PORT (CLK,RST,EN: IN STD_LOGIC;
DOUT: OUT STD_LOGIC_VECTOR (4 DOWNTO 0);
COUT: OUT STD_LOGIC);
END ENTITY CNT20;
ARCHITECTURE ART OF CNT20 IS
BEGIN
PROCESS(CLK,RST,EN)
VARIABLE Q:STD_LOGIC_VECTOR(4 DOWNTO 0):="10011";
BEGIN
IF RST='0' THEN Q:="00000";
ELSE
IF EN='0' THEN Q :="00000";
ELSIF EN='1' THEN
IF CLK'EVENT AND CLK='1' THEN
IF Q>0 THEN Q:=Q-1;
ELSE Q:="10011";
END IF;
END IF;
END IF;
END IF;
IF Q="00000" THEN COUT<='1';
ELSE COUT<='0';
END IF;
DOUT<=Q;
END PROCESS;
END ARCHITECTURE ART;
- LED状态显示模块程序
--//********LED状态显示模块********//
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY led1 IS
PORT(clk:IN STD_LOGIC;
rst:IN STD_LOGIC;
Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
W:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
E:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END led1 ;
ARCHITECTURE one OF led1 IS
SIGNAL num :INTEGER RANGE 7 DOWNTO 0;
BEGIN
PROCESS(clk)
BEGIN
IF rst='0' THEN num<=0;
ELSIF clk'EVENT AND clk='1' THEN
if num <=7 then num<=num+1;
else num<=0;
end if;
end if;
end process;
process(num)
begin
CASE num IS
WHEN 0 =>Q<="01111111";
WHEN 1 =>Q<="10111111";
WHEN 2 =>Q<="11011111";
WHEN 3 =>Q<="11101111";
WHEN 4 =>Q<="11110111";
WHEN 5 =>Q<="11111011";
WHEN 6 =>Q<="11111101";
WHEN 7 =>Q<="11111110";
WHEN OTHERS =>null;
END CASE;
CASE num IS
WHEN 0 =>W<="11111110";
WHEN 1 =>W<="11111101";
WHEN 2 =>W<="11111011";
WHEN 3 =>W<="11110111";
WHEN 4 =>W<="11101111";
WHEN 5 =>W<="11011111";
WHEN 6 =>W<="10111111";
WHEN 7 =>W<="01111111";
WHEN OTHERS =>null;
END CASE;
CASE num IS
WHEN 0 =>E<="00000000";--lED全排灭再全排亮
WHEN 1 =>E<="11111111";
WHEN 2 =>E<="00000000";
WHEN 3 =>E<="11111111";
WHEN 4 =>E<="00000000";
WHEN 5 =>E<="11111111";
WHEN 6 =>E<="00000000";
WHEN 7 =>E<="11111111";
WHEN OTHERS =>null;
END CASE;
END PROCESS;
END one;
- 数码管显示模块程序
--//********数码管显示模块********//
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY SHUMAGUAN IS
PORT(CLK,RST,EN: IN STD_LOGIC;
A: IN STD_LOGIC_VECTOR(4 DOWNTO 0);
LED8S: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--位选
LED7S: OUT STD_LOGIC_VECTOR(6 DOWNTO 0));--段选
END;
ARCHITECTURE behav OF SHUMAGUAN IS
TYPE states IS (s0,s1,s2);
SIGNAL YT :states:=s0 ;
--SIGNAL YU :states:=s3 ;
BEGIN
P1:PROCESS(CLK,RST,EN)
BEGIN
if RST='0' then
YT <= s0;
else
if CLK'event and CLK ='1' then
CASE YT IS
WHEN s0=> YT <=s1;
WHEN s1=> YT <=s2;
WHEN s2=> YT <=s0;
WHEN OTHERS => YT <=s0;
END CASE;
end if;
end if;
END PROCESS;
P2:PROCESS(YT,A)
VARIABLE YU:STD_LOGIC_VECTOR(1 DOWNTO 0):="00";
BEGIN
IF EN'event and EN ='1' THEN
CASE YU IS
WHEN "00"=>YU:="01";
WHEN "01"=>YU:="10";
WHEN "10"=>YU:="00";
WHEN OTHERS =>YU:="00";
end case;
end if;
IF YT=s0 then
CASE YU IS
WHEN "00" => LED7S(6 DOWNTO 0) <= "1001111";-- one
WHEN "01" => LED7S(6 DOWNTO 0) <= "0010010";-- two
WHEN "10" => LED7S(6 DOWNTO 0) <= "0000110";-- three
WHEN OTHERS=>NULL;
END CASE;
LED8S <= "01111111";--显示模式
ELSIF YT=s1 then
LED8S(7 DOWNTO 0)<="11111101";-- 计时倒数第一位数
CASE A IS
WHEN "00000" => led7s(6 DOWNTO 0) <= "0000001";--00
WHEN "00001" => led7s(6 DOWNTO 0) <= "0000001";--01
WHEN "00010" => led7s(6 DOWNTO 0) <= "0000001";--02
WHEN "00011" => led7s(6 DOWNTO 0) <= "0000001";--03
WHEN "00100" => led7s(6 DOWNTO 0) <= "0000001";--04
WHEN "00101" => led7s(6 DOWNTO 0) <= "0000001";--05
WHEN "00110" => led7s(6 DOWNTO 0) <= "0000001";--06
WHEN "00111" => led7s(6 DOWNTO 0) <= "0000001";--07
WHEN "01000" => led7s(6 DOWNTO 0) <= "0000001";--08
WHEN "01001" => led7s(6 DOWNTO 0) <= "0000001";--09
WHEN "01010" => led7s(6 DOWNTO 0) <= "1001111";--10
WHEN "01011" => led7s(6 DOWNTO 0) <= "1001111";--11
WHEN "01100" => led7s(6 DOWNTO 0) <= "1001111";--12
WHEN "01101" => led7s(6 DOWNTO 0) <= "1001111";--13
WHEN "01110" => led7s(6 DOWNTO 0) <= "1001111";--14
WHEN "01111" => led7s(6 DOWNTO 0) <= "1001111";--15
WHEN "10000" => led7s(6 DOWNTO 0) <= "1001111";--16
WHEN "10001" => led7s(6 DOWNTO 0) <= "1001111";--17
WHEN "10010" => led7s(6 DOWNTO 0) <= "1001111";--18
WHEN "10011" => led7s(6 DOWNTO 0) <= "1001111";--19
WHEN OTHERS=>NULL;
END CASE;
ELSIF YT=s2 then
LED8S(7 DOWNTO 0)<="11111110";-- 计时倒数第二位数
CASE A IS
WHEN "00000" => led7s(6 DOWNTO 0) <= "0000001";--00
WHEN "00001" => led7s(6 DOWNTO 0) <= "1001111";--1
WHEN "00010" => led7s(6 DOWNTO 0) <= "0010010";--2
WHEN "00011" => led7s(6 DOWNTO 0) <= "0000110";--3
WHEN "00100" => led7s(6 DOWNTO 0) <= "1001100";--4
WHEN "00101" => led7s(6 DOWNTO 0) <= "0100100";--5
WHEN "00110" => led7s(6 DOWNTO 0) <= "0100000";--6
WHEN "00111" => led7s(6 DOWNTO 0) <= "0001111";--7
WHEN "01000" => led7s(6 DOWNTO 0) <= "0000000";--8
WHEN "01001" => led7s(6 DOWNTO 0) <= "0000100";--9
WHEN "01010" => led7s(6 DOWNTO 0) <= "0000001";--10
WHEN "01011" => led7s(6 DOWNTO 0) <= "1001111";--11
WHEN "01100" => led7s(6 DOWNTO 0) <= "0010010";--12
WHEN "01101" => led7s(6 DOWNTO 0) <= "0000110";--13
WHEN "01110" => led7s(6 DOWNTO 0) <= "1001100";--14
WHEN "01111" => led7s(6 DOWNTO 0) <= "0100100";--15
WHEN "10000" => led7s(6 DOWNTO 0) <= "0100000";--16
WHEN "10001" => led7s(6 DOWNTO 0) <= "0001111";--17
WHEN "10010" => led7s(6 DOWNTO 0) <= "0000000";--18
WHEN "10011" => led7s(6 DOWNTO 0) <= "0000100";--19
WHEN OTHERS=>NULL;
END CASE;
END IF;
END PROCESS P2;
END behav;
- 控制模块程序
--//********控制模块********//
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ledkz IS
PORT( CLK,RST: IN STD_LOGIC;
Q1,Q2,Q3: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
T: OUT STD_LOGIC_VECTOR(7 DOWNTO 0) );
END ledkz ;
ARCHITECTURE behav OF ledkz IS
TYPE states IS (s0,s1,s2);
SIGNAL YT :states ;
BEGIN
P1:PROCESS(CLK,RST)
BEGIN
if rst='0' then YT<=s0;
elsif CLK'event and CLK ='1' then
CASE YT IS
WHEN s0=> YT <=s1;
WHEN s1=> YT <=s2;
WHEN s2=> YT <=s0;
WHEN OTHERS => YT <=s0;
END CASE;
end if;
END PROCESS;
P2:PROCESS(YT)
BEGIN
CASE YT IS
WHEN s0 => T(7 DOWNTO 0)<=Q1(7 DOWNTO 0);
WHEN s1 => T(7 DOWNTO 0)<=Q2(7 DOWNTO 0);
WHEN s2 => T(7 DOWNTO 0)<=Q3(7 DOWNTO 0);
WHEN OTHERS=> T(7 DOWNTO 0)<=Q1(7 DOWNTO 0);
END CASE;
END PROCESS P2;
END behav;