无法在7段上运行十进制数

时间:2014-05-13 20:11:50

标签: vhdl

我是初学者,请原谅我的代码逻辑。我试图通过计数器在7段上显示20个值。当该值大于9时,选择第二个段。当我运行这段代码时,我的第一段闪烁非常快,第二段闪烁。我知道我已经为我已经为段分配值的情况做了一些错误。我在这里失踪了什么?我的预分值是48Hz。任何想法?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity counter is
Port ( clk : in  STD_LOGIC;
            segment : out  STD_LOGIC_VECTOR (6 downto 0);
            anode: out std_logic_vector (3 downto 0) );
end counter;

architecture Behavioral of counter is
constant prescaler: STD_LOGIC_VECTOR(16 downto 0) := "00000000000110000";
signal prescaler_counter: STD_LOGIC_VECTOR(16 downto 0) := (others => '0');
signal counter: std_logic_vector (19 downto 0):= (others => '0');
signal r_anode: std_logic_vector (3 downto 0):= (others => '0');
begin
  process (clk) begin
  if (clk'event and clk = '1') then
    prescaler_counter <= std_logic_vector (unsigned(prescaler_counter) + 1);
        if(prescaler_counter = prescaler) then
                counter <= std_logic_vector (unsigned(counter)+1);
            end if;
   end if;
  end process;

anode <= r_anode;

 process  (counter) begin
  if (counter > "00000000000000001001") then
    r_anode <= "1110"; 
  else
    r_anode <= "1101";
 end if;    
 case counter is
 when "00000000000000000000" => segment <= "0000001"; --0
 when "00000000000000000001" => segment <= "1001111"; --1
 when "00000000000000000010" => segment <= "0010010"; --2
 when "00000000000000000011" => segment <= "0000110"; --3
 when "00000000000000000100" => segment <= "1001100"; --4
 when "00000000000000000101" => segment <= "0100100"; --5
 when "00000000000000000110" => segment <= "0100000"; --6
 when "00000000000000000111" => segment <= "0001111"; --7
 when "00000000000000001000" => segment <= "0000000"; --8
 when "00000000000000001001" => segment <= "0000100"; --9   
 when others => segment <= "1111111"; 
 end case;  
 end process;

end Behavioral;

3 个答案:

答案 0 :(得分:0)

对于一个数字,48Hz仍然可以很快地循环显示10个值,但如果这是你想要的......(如果你放慢速度,那么问题可能会变得更加明显,顺便说一下)

问题在于您的计数流程,您如何设置r_anode以及您的案例陈述以确定segment的值,可能还包括其他内容。

  1. 你的计数过程从1开始,很多,很多,你只想去20,据我所知。您可能需要考虑添加环绕条件。这取决于你如何做以下事情。

  2. r_anode"1110" 10个时钟,然后"1101"为剩余的2 ^ 20个周期。我不认为这是你想要的。顺便说一句,使用numeric_std,您只需编写unsigned(counter) > 9 - 我不确定您编写的内容是否应该编译(您之前使用的是std_logic_unsigned,我收集了吗?)

  3. 这是主要问题。您似乎希望两个数字的值都依赖于这一个计数器,但您要比较整个20位counter值,因此段仅在2 ^ 20中有效10个时钟,并且仅在第一个数字上,因为您只是显式检查值0到9.您需要的是某种模数运算(或每个数字的单独计数器或其他)。

  4. 您可能还需要考虑如何驾驶两个显示器,但这取决于您如何解决其他问题。

答案 1 :(得分:0)

当fru1bat回答时,我正准备好显示它。它可以提供照明:

counter_tb

注意为了方便起见,我使用了10 ns的时钟。

第一个数字经过它的计数(在片段上看到)然后切换到另一个数字,其他部分显示其他数字的选择):

process  (counter) 
begin
    if (counter > "00000000000000001001") then
        r_anode <= "1110"; 
    else
        r_anode <= "1101";
    end if;    
    case counter is
        when "00000000000000000000" => segment <= "0000001"; --0
        when "00000000000000000001" => segment <= "1001111"; --1
        when "00000000000000000010" => segment <= "0010010"; --2
        when "00000000000000000011" => segment <= "0000110"; --3
        when "00000000000000000100" => segment <= "1001100"; --4
        when "00000000000000000101" => segment <= "0100100"; --5
        when "00000000000000000110" => segment <= "0100000"; --6
        when "00000000000000000111" => segment <= "0001111"; --7
        when "00000000000000001000" => segment <= "0000000"; --8
        when "00000000000000001001" => segment <= "0000100"; --9   
        when others => segment <= "1111111"; 
    end case;  
end process;

从中我们可以想象你会看到“快速”中的每个细分市场。数字闪烁,然后是等待计数器翻转的长间隔,然后再次闪烁。

预分频计数器和计数器都显得太长了。

您想要切换启用的阳极,这意味着开关应该在一个数字和另一个数字之间。这应该比48 Hz更快一点。 (LCD或LED?)。

您希望驱动段的计数器慢得多。以48 Hz开始,使用计数器的LSB在两个显示位数之间切换阳极值。使用位于计数器另一端的位来驱动七个分段转换。您希望数字变得足够慢以便查看。另请注意,因为计数器不是BCD计数器(现在有一个想法),当任何四位作为聚合时大于9时,将显示空白显示时间。

你总是可以驾驶0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F(通过修改你的案例陈述)。这将允许您选择一个预分频器值,使您的闪烁最小。

我不建议简单地模拟你的设计,我这样做是为了让fru1bat覆盖相同的点。我想要这张照片。我在大约1/10的时间里停了下来(跑了2秒钟,得到了186 MB的时钟转换)。

答案 2 :(得分:0)

我发布了这段代码,由于@ fru1bat和@David,我想出了我的错误。是的我使用的是20位计数器,这对我来说真的很愚蠢,所以我使用了一个5位计数器并用这个延迟代码减慢了我的时钟。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity delay is
Port ( clk : in  STD_LOGIC;
       a : in  STD_LOGIC_VECTOR (31 downto 0);
       flag : out  STD_LOGIC);
end delay;

architecture Behavioral of delay is
signal count :integer:=0;
    begin
    process(clk) begin

        if(clk'event and clk='1') then
            count <= count +1;   --increment counter.
        end if;
        --see whether counter value is reached,if yes set the flag.
            if(count = to_integer (unsigned(a))) then 
                count <= 0;
                flag <='1';
            else
                flag <='0';
            end if;
    end process;

end Behavioral

然后我在我的7段代码中使用了这段代码,现在只打开一段,它从0开始直到9,到达9后计数器重置。现在我的问题是我应该如何显示两位数?我应该在这里使用双重算法吗?或者是什么?我的闪烁的基本问题现在已经消失了我需要打开第二段以使用相同的代码显示两位数。我该如何修改我的代码?有任何想法吗?这是我最后的一位数代码!

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity counter is
Port ( clk : in  STD_LOGIC;
            segment : out  STD_LOGIC_VECTOR (6 downto 0);
            anode: out std_logic_vector (3 downto 0) );
end counter;

 architecture Behavioral of counter is

 component delay
 Port ( clk : in  STD_LOGIC;
       a : in  STD_LOGIC_VECTOR (31 downto 0);
       flag : out  STD_LOGIC);
end component;

signal flag : std_logic :='0';
signal delay_needed : std_logic_vector(31 downto 0); 
constant countvalue: STD_LOGIC_VECTOR (4 downto 0) := "01001";
signal counter: std_logic_vector (4 downto 0):= (others => '0');
    signal r_anode: std_logic_vector (3 downto 0):= (others => '0');

begin
    delay_needed <=  "00000001011111010111100001000000";  --25000000 in binary

    inst_delay : delay port map(clk,delay_needed,flag);  

 process (flag) begin

  if (flag'event and flag = '1') then
        counter <= std_logic_vector (unsigned(counter)+1);
            if (counter = countvalue) then
                counter <= (others => '0');
            end if;
    end if;
  end process;

        anode <= r_anode;
        r_anode <= "1110"; 

process (counter, r_anode) begin
case r_anode is 
        when "1110" => case counter is 
                                    when "00000" => segment <= "0000001"; --0
                                    when "00001" => segment <= "1001111"; --1
                                    when "00010" => segment <= "0010010"; --2
                                    when "00011" => segment <= "0000110"; --3
                                    when "00100" => segment <= "1001100"; --4
                                    when "00101" => segment <= "0100100"; --5
                                    when "00110" => segment <= "0100000"; --6
                                    when "00111" => segment <= "0001111"; --7
                                    when "01000" => segment <= "0000000"; --8
                                    when "01001" => segment <= "0000100"; --9
                                    when others => segment <= "1111111";
                                    end case;
    when others => segment <= "1111111";
    end case;   
 end process;

end Behavioral;