一、设计目的
- 掌握彩灯控制方法,了解状态机的应用
2. 掌握VHDL编程语言,了解实际设计中的优化方案
二、开发软件: QuartusII
三、设计任务
设计一个八路彩灯控制器,要求:
- 彩灯明暗变化节拍为0.25S和0.5S两种节拍,采用按键进行频率切换。
- 演示花型3种,分别为左移、右移、闪烁。每种花型显示时间维持20秒。
- 彩灯用发光二极管LED模拟。
四、任务分析:
1、该系统的外加信号为时钟,输出为8路彩灯信号。彩灯控制器按一定的节拍改变8路输出的高低电平,控制彩灯按预定的规律亮灭,从而显示一定的花型。根据设计任务,彩灯控制器应包含时钟电路编码器和控制电路。时钟可以采用全局时钟分频后时钟输出信号;编码器根据花型要求按节拍产生8位输出编码信号,控制彩灯按规律亮灭;控制电路则应控制编码器的节拍脉冲和3种花形的循环切换,同步整个系统工作。
2、 选择48MHZ时钟脉冲作为系统时钟。
3、0.25S和0.5S秒信号由时钟分频获得。
4、循环显示方式自定:可以按照左移-闪烁-右移-左移方式显示,也可以按照其他方式显示。
五、设计方案
利用EDA语言设计二选一选择器、分频器、彩灯控制、显示控制的程序。用原理图输入设计法,连接各控制器,并将其下载到实验箱中,通过硬件显示彩灯变化。为了方便计时。本项目采用数码管每个花色正计时20s来显示时间。
其中,顶层文件采用原理图输入法,如下图所示:
两个分频模块(int_div)输出频率分别为2Hz和4Hz,经由二选一模块mux_21A,选择不同的输入频率到三种LED花型控制模块LED1,LED2,LED3。再进入三选一选择器mux_31A,选择要输出的花型。在控制花型变换以及时间方面,本装置采用预分频后,进入三级计数器,来达成数码管显示所用20秒正计数时间控制,并在最后一级计数器输出三选一选择器所需要的选择信号。
DECL7S模块集成了七段数码管段选码译码输出以及位码选择输出。
具体代码如下:
分频模块:
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL ;
ENTITY PULSE IS
GENERIC( N: INTEGER:=23999999 ) ;
PORT(CLK: IN STD_LOGIC;
Fout: OUT STD_LOGIC);
END ;
ARCHITECTURE ONE OF PULSE IS
SIGNAL FULL : STD_LOGIC;
BEGIN
PRO1: PROCESS(CLK)
VARIABLE CNT1 : INTEGER RANGE 48000000 DOWNTO 0;
BEGIN
IF CLK'EVENT AND CLK = '1' THEN
IF CNT1 = N THEN
CNT1 := 0;
FULL <= '1';
ELSE CNT1 :=CNT1 + 1;
FULL <= '0';
END IF;
END IF;
END PROCESS;
PRO2 : PROCESS(FULL)
VARIABLE CNT2 : STD_LOGIC;
BEGIN
IF FULL'EVENT AND FULL = '1' THEN
CNT2 := NOT CNT2;
IF CNT2 = '1' THEN
Fout <= '1';
ELSE Fout <= '0';
END IF;
END IF;
END PROCESS;
END;
花色控制模块LED1:
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)); --实验室改成8位
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 NUM<=NUM+1;
END IF;
END PROCESS;
PROCESS(NUM)
BEGIN
CASE NUM IS
WHEN 0 =>Q<="01111111"; --实验室改成8位
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;
END PROCESS;
END;
花色控制模块LED2:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY led2 IS PORT(CLK:IN STD_LOGIC;
RST:IN STD_LOGIC;
Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --实验室改成8位
END led2;
ARCHITECTURE one OF led2 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<="00000000"; --实验室改成8位
WHEN 1 =>Q<="11111111";
WHEN 2 =>Q<="00000000";
WHEN 3 =>Q<="11111111";
WHEN 4 =>Q<="00000000";
WHEN 5 =>Q<="11111111";
WHEN 6 =>Q<="00000000";
WHEN 7 =>Q<="11111111";
WHEN OTHERS =>NULL;
END CASE;
END PROCESS;
END one;
花色控制模块LED3:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY led3 IS
PORT( CLK:IN STD_LOGIC;
RST:IN STD_LOGIC;
Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --实验室改成8位
END led3;
ARCHITECTURE one OF led3 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<="11111110"; --实验室改成8位
WHEN 1 =>Q<="11111101";
WHEN 2 =>Q<="11111011";
WHEN 3 =>Q<="11110111";
WHEN 4 =>Q<="11101111";
WHEN 5 =>Q<="11011111";
WHEN 6 =>Q<="10111111";
WHEN 7 =>Q<="01111111";
WHEN OTHERS =>NULL;
END CASE;
END PROCESS;
END one;
数码管译码显示模块DECL7S
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL ;
use ieee.std_logic_unsigned.all;
ENTITY DECL7S IS
PORT ( clk : in std_logic;
ge : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
shi : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
ceshi_c : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
LED7S : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
LED7b : out std_logic_vector(5 downto 0)) ;
END;
ARCHITECTURE one OF DECL7S IS
signal cnt_2 : std_logic_vector(1 downto 0);
signal a :std_logic_vector(3 downto 0);
BEGIN
p1:PROCESS(cnt_2)
BEGIN
case cnt_2 is
when "00"=> LED7b <= "111110";a<=ge;
when "01"=> LED7b <= "111101";a<=shi;
when "10"=> LED7b <= "101111";a<=ceshi_c;
when "11"=> LED7b <= "011111";a<="0000";
end case;
end process p1;
p2:PROCESS(A)
begin
CASE A IS
WHEN "0000" => LED7S <= "1000000" ; --共阳数码管
WHEN "0001" => LED7S <= "1111001" ;
WHEN "0010" => LED7S <= "0100100" ;
WHEN "0011" => LED7S <= "0110000" ;
WHEN "0100" => LED7S <= "0011001" ;
WHEN "0101" => LED7S <= "0010010" ;
WHEN "0110" => LED7S <= "0000010" ;
WHEN "0111" => LED7S <= "1111000" ;
WHEN "1000" => LED7S <= "0000000" ;
WHEN "1001" => LED7S <= "0010000" ;
WHEN OTHERS => NULL ;
END CASE ;
END PROCESS p2;
p3:process(clk)
begin
if clk'event and clk='1' then
cnt_2<=cnt_2+1;
end if;
end process p3;
END ;
篇幅原因,计数器和选择器模块程序不再赘述