4位共阴极数码管的动态扫描电路VHDL设计

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

--功能:利用4位共阴极动态数码管实现模值为100的计数器,计数区间0~99,无进位输出
--原理:动态扫描电路,时钟分频,段选位选

entity led is
port (
    clkin:in std_logic;--时钟输入,也是唯一的输入
    clkout:out std_logic_vector(6 downto 0);--段选输出
    enout:out std_logic_vector(3 downto 0)--位选输出
);
end entity;

architecture behav of led is
    signal q1: std_logic_vector(6 downto 0);--存储1号管的选段(低位)
    signal q2: std_logic_vector(6 downto 0);--存储2号管的选段(高位)
    signal qout: std_logic_vector(6 downto 0);--存储2号管的选段(高位)
    constant led_num: integer := 2;--使用的数码管数量,限选1~4位,这里使用2个
    constant freq: integer := 1000 / led_num;--分频公式,用于计算每秒多少次脉冲,这里以1KHz时钟为准
begin 
    process(clkin)--对时钟脉冲进行处理
        variable var_bit: integer range 0 to led_num+1:=0;--变量,用于选位,0代表初始化
        variable var_cnt_bit1 : integer range 0 to freq:=0;--变量,用于1号管(低位)的时钟计数
        variable var_cnt_bit2 : integer range 0 to freq*10:=0;--变量,用于2号管(高位)的时钟计数
        variable var_num1 : integer range 0 to 10:=0;--变量,存储1号(低位)管的值,格式为十进制
        variable var_num2 : integer range 0 to 10:=0;--变量,存储2号(高位)管的值,格式为十进制
    begin
        if(clkin'event and clkin='1')then --开始等待和处理脉冲
            --循环选位,从1开始,1-2交替------------
            var_bit := var_bit + 1;
            if(var_bit=3) then
                var_bit := 1;
            end if;
            ------------------------------------
            
            --进位时,更新高位数码管的值------------
            if(var_num1=10)then
                var_bit := 2;
            end if;
            ------------------------------------
            
            --判断位值---------------------------
            case var_bit is
                when 1=> --低位管
                    enout <="0001";
                    var_cnt_bit1 := var_cnt_bit1 + 1;
                    if(var_cnt_bit1=freq)then
                        var_num1:= var_num1 + 1;
                        case var_num1 is--低位计数,段选,实现译码功能
                            when 1=> q1<="0000110";
                            when 2=> q1<="1011011";
                            when 3=> q1<="1001111";
                            when 4=> q1<="1100110";
                            when 5=> q1<="1101101";
                            when 6=> q1<="1111101";
                            when 7=> q1<="0000111";
                            when 8=> q1<="1111111";
                            when 9=> q1<="1101111";
                            when 10=> q1<="0111111";var_num1:=0;--逢10归0
                            when 0=> q1<="1111111";var_num1:=0;--这个0永远不显示,加上它是为了避免报错
                        end case;
                        var_cnt_bit1:=0;--时钟计数清0
                    end if;
                    qout <= q1;--clkout对外输出
                when 2=> --高位管
                    enout <="0010";
                    var_cnt_bit2 := var_cnt_bit2 + 1;
                    if(var_cnt_bit2=freq*10 or var_num1=10)then
                        var_num2:= var_num2 + 1;
                        case var_num2 is--高位计数,段选,实现译码功能
                            when 1=> q2<="0000110";
                            when 2=> q2<="1011011";
                            when 3=> q2<="1001111";
                            when 4=> q2<="1100110";
                            when 5=> q2<="1101101";
                            when 6=> q2<="1111101";
                            when 7=> q2<="0000111";
                            when 8=> q2<="1111111";
                            when 9=> q2<="1101111";
                            when 10=> q2<="0111111";var_num2:=0;--逢10归0
                            when 0=> q2<="1111111";var_num1:=0;--这个0永远不显示,加上它是为了避免报错
                        end case;
                        var_cnt_bit2:=0;--时钟计数清0
                    end if;
                    qout <= q2;--clkout对外输出
                when others=>var_bit:=var_bit;--防止报错
            end case;
            ---------------------------判断位值--
        end if;
    end process;
    clkout <= qout;
end behav;

 

posted @ 2019-05-28 18:31  NESTER  阅读(1793)  评论(0编辑  收藏  举报