我是初学者,请原谅我的代码逻辑。我试图通过计数器在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;
答案 0 :(得分:0)
问题在于您的计数流程,您如何设置r_anode
以及您的案例陈述以确定segment
的值,可能还包括其他内容。
你的计数过程从1开始,很多,很多,你只想去20,据我所知。您可能需要考虑添加环绕条件。这取决于你如何做以下事情。
r_anode
为"1110"
10个时钟,然后"1101"
为剩余的2 ^ 20个周期。我不认为这是你想要的。顺便说一句,使用numeric_std
,您只需编写unsigned(counter) > 9
- 我不确定您编写的内容是否应该编译(您之前使用的是std_logic_unsigned
,我收集了吗?)
这是主要问题。您似乎希望两个数字的值都依赖于这一个计数器,但您要比较整个20位counter
值,因此段仅在2 ^ 20中有效10个时钟,并且仅在第一个数字上,因为您只是显式检查值0到9.您需要的是某种模数运算(或每个数字的单独计数器或其他)。
您可能还需要考虑如何驾驶两个显示器,但这取决于您如何解决其他问题。
答案 1 :(得分:0)
当fru1bat回答时,我正准备好显示它。它可以提供照明:
注意为了方便起见,我使用了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;