我想通过按适当的开关在4位7段显示器上显示3位二进制。 例如:-如果开关位置为001(开关2-关闭开关1-关闭开关0-开启) 那么我想在7段显示器上显示001。 我使用VHDL执行此操作。 尝试多路复用,但仍然无法正常工作。 下面是代码。
entity test is
Port(Seg_AN :out std_logic_vector(3 downto 0);
Seg7 :out std_logic_vector(6 downto 0);
SWITCH :in std_logic_vector(2 downto 0);
CLK :in std_logic
);
end test;
architecture Behavioral of test is
signal sel :natural range 0 to 8;
signal anode_sel :std_logic_vector(2 downto 0);
-- signal number :std_logic_vector(2 downto 0);
constant c_cnt_200hz :natural := 87500;
-- constant c_cnt_1hz :natural := 17500000;
signal r_cnt_200hz :natural range 0 to c_cnt_200hz;
-- signal r_cnt_1hz :natural range 0 to c_cnt_1hz;
signal anode :std_logic_vector(2 downto 0);
signal segment :std_logic_vector(6 downto 0);
-- signal digit :std_logic;
begin
process(CLK)
begin
if rising_edge(CLK) then
if r_cnt_200hz = c_cnt_200hz - 1 then
r_cnt_200hz <= 0;
if sel = 8 then
sel <= 0;
else
sel <= sel + 1;
end if;
else
r_cnt_200hz <= r_cnt_200hz + 1;
end if;
end if;
end process;
process(sel)
begin
case sel is
when 1 => anode_sel <= "001";
when 2 => anode_sel <= "010";
when 3 => anode_sel <= "100";
when 4 => anode_sel <= "011";
when 5 => anode_sel <= "101";
when 6 => anode_sel <= "110";
when others => anode_sel <= "111";
end case;
anode <= not anode_sel;
end process;
process(anode)
begin
if SWITCH(0)='1' or SWITCH(1)='1' or SWITCH(2)='1' then
segment <= "1111001";
else
segment <= "1000000";
end if;
end process;
Seg_AN <= '1' & anode;
Seg7 <= segment;
end Behavioral;
答案 0 :(得分:1)
请参考下图:
要显示一个,您需要B和C接通。
要显示零,您需要A,B,C,D,E,F。
因此,实际上您只需要打开或关闭A,D,E,F。 对于一个,它们需要关闭,对于零,则需要打开。
您的代码需要:
始终保持B和C。 (两个不变的输出)
始终保持关闭状态。 (第三个输出不变)
根据位开关的位置同时打开或关闭所有A,D,E,F。那是四个具有相同值的输出。
唯一的问题是是否需要逆变器。这取决于开关和/或LED是否连接为高电平有效或低电平有效。
答案 1 :(得分:0)
我建议通过纯组合逻辑来实现该解决方案,您实际上并不需要寄存器(使用时钟的上升/下降沿时已合成)。
您可以在时钟之外为它计时(通过一些寄存器输入)。
LIBRARY ieee;
USE ieee.std_logic_1164.all;
Entity SEG7_LUT is
port( oSEG : out std_logic_vector (6 downto 0);
iDIG : in std_logic_vector (3 downto 0));
end entity SEG7_LUT;
Architecture RTL of SEG7_LUT is
begin
logic : process (iDIG) begin
case iDIG is
when x"1" => oSEG <= "1111001";
when x"2" => oSEG <= "0100100"; -- |--rt--|
when x"3" => oSEG <= "0110000"; -- lt rt
when x"4" => oSEG <= "0011001"; -- | |
when x"5" => oSEG <= "0010010"; -- ---m----
when x"6" => oSEG <= "0000010"; -- | |
when x"7" => oSEG <= "1111000"; -- lb rb
when x"8" => oSEG <= "0000000"; -- | |
when x"9" => oSEG <= "0011000"; -- ---b----
when x"a" => oSEG <= "0001000";
when x"b" => oSEG <= "0000011";
when x"c" => oSEG <= "1000110";
when x"d" => oSEG <= "0100001";
when x"e" => oSEG <= "0000110";
when x"f" => oSEG <= "0001110";
when x"0" => oSEG <= "1000000";
end case;
end process logic;
end;
下面的代码给出了一个示例,它在八个7段显示器上以十六进制格式表示32位数字。
LIBRARY ieee;
USE ieee.std_logic_1164.all;
Entity SEG7_LUT_8 is
port( oSEG0 : out std_logic_vector (6 downto 0);
oSEG1 : out std_logic_vector (6 downto 0);
oSEG2 : out std_logic_vector (6 downto 0);
oSEG3 : out std_logic_vector (6 downto 0);
oSEG4 : out std_logic_vector (6 downto 0);
oSEG5 : out std_logic_vector (6 downto 0);
oSEG6 : out std_logic_vector (6 downto 0);
oSEG7 : out std_logic_vector (6 downto 0);
iDIG : in std_logic_vector (31 downto 0));
end;
Architecture RTL of SEG7_LUT_8 is
begin
u0 : entity work.SEG7_LUT port map( oSEG0,iDIG(3 downto 0) );
u1 : entity work.SEG7_LUT port map(oSEG1,iDIG(7 downto 4) );
u2 : entity work.SEG7_LUT port map(oSEG2,iDIG(11 downto 8) );
u3 : entity work.SEG7_LUT port map(oSEG3,iDIG(15 downto 12) );
u4 : entity work.SEG7_LUT port map(oSEG4,iDIG(19 downto 16) );
u5 : entity work.SEG7_LUT port map(oSEG5,iDIG(23 downto 20) );
u6 : entity work.SEG7_LUT port map(oSEG6,iDIG(27 downto 24) );
u7 : entity work.SEG7_LUT port map(oSEG7,iDIG(31 downto 28) );
end;