VHDL的数码管驱动原理

如题,看下面的程序时一直不明白程序如何实现让8个数码管分别显示,(也就是位控制部分),给出下面的程序,只要大概说明原理,并在程序的关键位置给出提示就好了。

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY SCAN_LED IS
PORT ( CLK : IN STD_LOGIC;
SG : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);--段控制信号输出
BT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0) );--位控制信号输出
END;
ARCHITECTURE one OF SCAN_LED IS
SIGNAL CNT8 : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL A : INTEGER RANGE 0 TO 15;
BEGIN
P1:process(CNT8)
BEGIN
CASE CNT8 IS
WHEN "000" => BT <= "0000" ; A <= 0 ;
WHEN "001" => BT <= "0001" ; A <= 6 ;
WHEN "010" => BT <= "0010" ; A <= 6 ;
WHEN "011" => BT <= "0011" ; A <= 2 ;
WHEN "100" => BT <= "0100" ; A <= 3 ;
WHEN "101" => BT <= "0101" ; A <= 0 ;
WHEN "110" => BT <= "0110" ; A <= 0 ;
WHEN "111" => BT <= "0111" ; A <= 7 ;
WHEN OTHERS => NULL ;
END CASE ;
END PROCESS P1;

P2:process(CNT8)
BEGIN
IF CLK'EVENT AND CLK = '1' THEN CNT8 <= CNT8 + 1;
END IF;
END PROCESS P2 ;
P3:process(A) BEGIN
CASE A IS
WHEN 0 => SG <= "0111111"; WHEN 1 => SG <= "0000110";
WHEN 2 => SG <= "1011011"; WHEN 3 => SG <= "1001111";
WHEN 4 => SG <= "1100110"; WHEN 5 => SG <= "1101101";
WHEN 6 => SG <= "1111101"; WHEN 7 => SG <= "0000111";
WHEN 8 => SG <= "1111111"; WHEN 9 => SG <= "1101111";
--WHEN 10=> SG <= "1110111"; WHEN 11 => SG <= "1111100";
-- WHEN 12=> SG <= "0111001"; WHEN 13 => SG <= "1011110";
-- WHEN 14=> SG <= "1111001"; WHEN 15 => SG <= "1110001";
WHEN OTHERS => NULL ;
END CASE ;
END PROCESS P3;
END;

先谢过了!

这是一个8位数码管动态扫描显示电路:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY SCAN_LED IS
PORT ( CLK : IN STD_LOGIC;
SG : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);--段控制信号输出
BT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0) );--位控制信号输出
END;
ARCHITECTURE one OF SCAN_LED IS
SIGNAL CNT8 : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL A : INTEGER RANGE 0 TO 15;
BEGIN
P1:process(CNT8)
BEGIN
CASE CNT8 IS
WHEN "000" => BT <= "0000" ; A <= 0 ;
WHEN "001" => BT <= "0001" ; A <= 6 ;
WHEN "010" => BT <= "0010" ; A <= 6 ;
WHEN "011" => BT <= "0011" ; A <= 2 ;
WHEN "100" => BT <= "0100" ; A <= 3 ;
WHEN "101" => BT <= "0101" ; A <= 0 ;
WHEN "110" => BT <= "0110" ; A <= 0 ;
WHEN "111" => BT <= "0111" ; A <= 7 ;
WHEN OTHERS => NULL ;
END CASE ;
END PROCESS P1;

P2:process(CNT8) --当时钟上升沿来到时进行加1,是一个模8的计数器。作用是产生扫描时钟----
BEGIN
IF CLK'EVENT AND CLK = '1' THEN CNT8 <= CNT8 + 1;
END IF;
END PROCESS P2 ;
P3:process(A) ----译码电路-----
BEGIN
CASE A IS
WHEN 0 => SG <= "0111111"; WHEN 1 => SG <= "0000110";
WHEN 2 => SG <= "1011011"; WHEN 3 => SG <= "1001111";
WHEN 4 => SG <= "1100110"; WHEN 5 => SG <= "1101101";
WHEN 6 => SG <= "1111101"; WHEN 7 => SG <= "0000111";
WHEN 8 => SG <= "1111111"; WHEN 9 => SG <= "1101111";
--WHEN 10=> SG <= "1110111"; WHEN 11 => SG <= "1111100";
-- WHEN 12=> SG <= "0111001"; WHEN 13 => SG <= "1011110";
-- WHEN 14=> SG <= "1111001"; WHEN 15 => SG <= "1110001";
WHEN OTHERS => NULL ;
END CASE ;
END PROCESS P3;
END;

8个数码管分别由位选BT0-BT2控制。如果希望在8个数码管显示希望的数据,就必须使得8个数码管分别被单独选通;同时有段信号输入口加上希望在该对应数码管上显示的数据,于是随着选通信号的变化(加上人眼的视觉残留效果),实现了数码管动态扫描显示的目的。
此例中显示的是:70032660
温馨提示:内容为网友见解,仅供参考
第1个回答  2009-06-01
ARCHITECTURE one OF SCAN_LED IS
SIGNAL CNT8 : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL A : INTEGER RANGE 0 TO 15;
BEGIN
P1:process(CNT8) //这个是用来产生片选的,BT输出信号38译码后接数码管的共阴极或共阳极,本程序让数码管显示70032660或06623007(看数码管顺序)
BEGIN
CASE CNT8 IS
WHEN "000" => BT <= "0000" ; A <= 0 ;
WHEN "001" => BT <= "0001" ; A <= 6 ;
WHEN "010" => BT <= "0010" ; A <= 6 ;
WHEN "011" => BT <= "0011" ; A <= 2 ;
WHEN "100" => BT <= "0100" ; A <= 3 ;
WHEN "101" => BT <= "0101" ; A <= 0 ;
WHEN "110" => BT <= "0110" ; A <= 0 ;
WHEN "111" => BT <= "0111" ; A <= 7 ;
WHEN OTHERS => NULL ;
END CASE ;
END PROCESS P1;

P2:process(CNT8)
BEGIN //这是扫描部分,在每个时钟上升沿让下一个数码管
选中,如果选中第八个,下一个时钟到来时,又选中第一个
IF CLK'EVENT AND CLK = '1' THEN CNT8 <= CNT8 + 1;
END IF;
END PROCESS P2 ; //这是数码管字型显示,SG是字型码,分别对应0到f(十六进制),显示内容由A决定
P3:process(A) BEGIN
CASE A IS
WHEN 0 => SG <= "0111111"; WHEN 1 => SG <= "0000110";
WHEN 2 => SG <= "1011011"; WHEN 3 => SG <= "1001111";
WHEN 4 => SG <= "1100110"; WHEN 5 => SG <= "1101101";
WHEN 6 => SG <= "1111101"; WHEN 7 => SG <= "0000111";
WHEN 8 => SG <= "1111111"; WHEN 9 => SG <= "1101111";
--WHEN 10=> SG <= "1110111"; WHEN 11 => SG <= "1111100";
-- WHEN 12=> SG <= "0111001"; WHEN 13 => SG <= "1011110";
-- WHEN 14=> SG <= "1111001"; WHEN 15 => SG <= "1110001";
WHEN OTHERS => NULL ;
END CASE ;
END PROCESS P3;
END;
第2个回答  2009-06-01
这是共阴数码管,段码都接低电平,相当于0,位码若接高电平1,则数码管亮一条。仔细观察数码管,是不是有7段?分别从高位到低位是gfedcba,还有角落里有个小圆点,也算一位的,是h,组合起来就是hgfedcba。从你程序上看,只有七段,也就是忽略了最高位,所以SG <= "0111111,相当于g=0,f=1,e=1,d=1,c=1,b=1,a=1。此时,数码管中间一条不亮,刚好显示是阿拉伯数字0。其他以此类推。
哎,这样一时很难说清楚的,自己去理解吧,不懂再问我。
第3个回答  2009-06-01
照程序看来,A是控制每个数码管显示的内容的,那么BT应该是控制8个数码管动态显示的,通常BT应该设为8位,00000001 00000010 00000100等等分别控制1个数码管,会不会硬件上有74LS138之类的译码电路呢
相似回答