本文为大家带来四种不同的vhdl数码管动态扫描程序设计。
vhdl数码管动态扫描一:循环滚动
实现的功能
循环滚动,始终点亮6个数码管,左出右进。状态为:012345-123450-234501-345012-450123-501234-012345
实现代码:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL
ENTITY LED2 IS
PORT(CLK:IN STD_LOGIC;
SG:OUT STD_LOGIC_VECTOR(6 DOWNTO 0); BT:OUT STD_LOGIC_VECTOR(5 DOWNTO 0)); END LED2;
ARCHITECTURE ACE OF LED2 IS component div_2K
port(clk_in:instd_logic; clk_out:outstd_logic);
end component;
SIGNAL CNT6:INTEGER RANGE 0 TO 5;
SIGNAL A:INTEGER RANGE 0 TO 5;
SIGNAL COUNT:INTEGER RANGE 0 TO 4999 := 0;
SIGNAl FLAG:INTEGER RANGE 0 TO 6 := 0;
SIGNAl FLAG_A:INTEGER RANGE 0 TO 5;
SIGNAL clk_tmp:STD_LOGIC;
BEGIN
u1:div_2k port map(clk_in=>CLK,clk_out=>clk_tmp);
P1:process(CNT6)
BEGIN
CASE CNT6 IS --3线至6线译码器
WHEN 0 => BT <= “011111” A <= 0 --A为位码
WHEN 1 => BT<= “101111” A <= 1
WHEN 2 => BT<= “110111” A <= 2
WHEN 3 => BT<= “111011” A <= 3
WHEN 4 => BT<= “111101” A <= 4
WHEN 5 => BT<= “111110” A <= 5
WHEN OTHERS => NULL;
END CASE
END PROCESS P1;
P2:process(clk_tmp)
BEGIN
IF clk_tmp‘EVENT AND clk_tmp= ’1‘ THEN --实现模6计数器 if CNT6= 5 then CNT6<= 0; else
CNT6<=CNT6 + 1; end if;
IF (FLAG = 6) THEN --设置标志 FLAG <= 0;
END IF;
IF COUNT =4999 THEN
--相当于另一个时钟
COUNT <= 0; --计数周期为5000
FLAG <=FLAG+1; --当记满5000时左移动一位 ELSE
COUNT <=COUNT+1; --不满5000继续计数 END IF; END IF;
END PROCESS P2;
P3:process(A,FLAG,FLAG_A)
BEGIN
FLAG_A<=(( A + FLAG )mod 6) --使用求余运算实现移位
CASE FLAG_A IS --实现数码管的显示功能
WHEN 0=> SG <= “1111110”;
WHEN 1=> SG <= “0110000”;
WHEN 2=> SG <= “1101101”;
WHEN 3=> SG <= “1111001”;
WHEN 4=> SG <=“0110011”;
WHEN 5=> SG <= “1011011”;
WHEN OTHERS =>NULL
END CASE
END PROCESS P3;
END ACE;
代码分析:
为实现移位,关键改动为新增一个计数器,技术周期远远大于扫描周期,这样,在一个大的计数周期内,对于要显示的6位数码进行动态扫描(和实验任务1中相同),显示出6种移位状态中的一种;在下一个大的周期内,利用FLAG标志,并使用求余运算将显示位的数码移位,比如,大的计数周期为0时,FLAG为0,显示“012345”六位数码,大的周期为1时,FALG为1,此时各位求余(即FLAG_A求余)对应的数码为123450,显示的数码也就为“123450”。以此类推,实现循环移位。