EDA实践——基于VHDL的循环八路彩灯设计

一、设计任务
设计一个八路彩灯控制器,要求:
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程序

  1. 任意整数分频模块程序
--//********任意整数分频模块********//
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;
  1. 二选一模块程序
--//********二选一模块********//
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;
  1. 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;
  1. 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;
  1. 数码管显示模块程序
--//********数码管显示模块********//
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;
  1. 控制模块程序
--//********控制模块********//
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;

猜你喜欢

转载自blog.csdn.net/Insincerity/article/details/113964666
今日推荐