7段显示的十进制数

时间:2014-01-01 08:07:15

标签: arrays vhdl

我的VHDL项目存在很大问题。我想在7段显示器上看到用户使用开关设置的数字。例如,如果打开低阶5开关,则它们将表示十进制数为31的二进制数“11111”。所以我想在7段显示中看到31。

为此,我计划了以下步骤:

  • 将交换机的5值插入数组
  • 将数组转换为整数
  • 查看整数到7段显示

第1点)插入数组

     signal first: std_logic_vector (0 to 4);
     signal temp: integer range 0 to 9999:=0;
     for i in 0 to 4 loop
           first(i)<=SW(i);
     end loop;
     temp<=VEC_TOINT(first);
     HEX0<=INT_TO7SEG(temp);

点2)向量整数

     Function VEC_TOINT(Vector: in std_logic_vector) return integer is
     variable temp: bit_vector(Vector'range);
     variable result: integer :=0;
     Begin
          for index in Vector'range loop
               result:=result * 2 + bit'pos(temp(index));
          end loop;
          if Vector(Vector'left) = '1' then 
               result:=(-result)-1;
          end if;
          return result;
     End VEC_TOINT;

目前第三点我不知道。

3 个答案:

答案 0 :(得分:2)

我写了一个小包,可以做你想要的。给定无符号输入值,它将该值分解为一系列十进制数字,并生成可驱动任意数量的七段显示的信号。

以下是您如何使用它的示例:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.seven_segment_pkg.all;

entity switches_to_7seg_displays is
    port (
        switches: in std_logic_vector(4 downto 0);
        seven_segments_display_1: out std_logic_vector(6 downto 0);
        seven_segments_display_2: out std_logic_vector(6 downto 0)
    );
end entity switches_to_7seg_displays;

architecture behavior of switches_to_7seg_displays is
    signal segments: std_logic_vector(13 downto 0);
    signal input: integer;
begin

    input <= to_integer(unsigned(switches));

    segments <= unsigned_to_seven_segment(
        value => unsigned(switches),
        number_of_digits => 2,
        value_is_bcd => false          
    );

    seven_segments_display_1 <= segments(13 downto 7);
    seven_segments_display_2 <= segments(6 downto 0);

end;

请注意,输入值是无符号的。要将std_logic_vector(实际上,“类型转换”)转换为无符号,只需使用:

switches_uns <= unsigned(switches_slv);

如果由于某种原因你决定将开关中的值转换为整数,那么ieee.numeric_std中就有一个函数可以做到这一点。使用它而不是自己编写它是个好主意。您可以将其用作:

switches_int <= to_integer(unsigned(switches_slv));

最后,这是包的代码。欢迎您使用或研究它并提出自己的解决方案。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package seven_segment_pkg is

    -- Return a std_logic_vector ready for driving a number of 7-segment displays.
    function unsigned_to_seven_segment(
        value: unsigned;
        number_of_digits: integer;
        value_is_bcd: boolean
    ) return std_logic_vector;

end;

package body seven_segment_pkg is

    function seven_seg_from_bcd_digit(bcd_digit: std_logic_vector(3 downto 0)) 
        return std_logic_vector 
    is begin
        case bcd_digit is
            --                   abcdefg
            when x"0" => return "0111111";
            when x"1" => return "0000110";
            when x"2" => return "1011011";
            when x"3" => return "1001111";
            when x"4" => return "1100110";
            when x"5" => return "1101101";
            when x"6" => return "1111101";
            when x"7" => return "0000111";
            when x"8" => return "1111111";
            when x"9" => return "1101111";
            when x"a" => return "1110111";
            when x"b" => return "1111100";
            when x"c" => return "0111001";
            when x"d" => return "1011110";
            when x"e" => return "1111001";
            when x"f" => return "1110001";
            when others => return "0000000";
        end case;
    end;

    -- Return a vector ready for driving a series of 7-segment displays.
    function unsigned_to_seven_segment(
        value: unsigned;
        -- Number of 7-segment displays (determines output vector width: W = 7*N)
        number_of_digits: integer;
        -- When true, treat the input value as a BCD number where every 4 bits hold one
        -- digit from 0 to A. When false, treat the input number as an unsigned integer.       
        value_is_bcd: boolean
    ) return std_logic_vector is

        variable segments: std_logic_vector(number_of_digits*7-1 downto 0);
        variable bcd_quotient: unsigned(value'range);
        variable bcd_remainder: unsigned(3 downto 0);
    begin

        if value_is_bcd then
            for i in 0 to number_of_digits-1 loop
                segments(i*7+6 downto i*7) := seven_seg_from_bcd_digit(
                    std_logic_vector(value(i*4+3 downto i*4))
                );
            end loop;
        else
            bcd_quotient := value;
            for i in 0 to number_of_digits-1 loop
                bcd_remainder := resize(bcd_quotient mod 10, 4);
                bcd_quotient := bcd_quotient / 10;
                segments(i*7+6 downto i*7) := seven_seg_from_bcd_digit(
                    std_logic_vector(bcd_remainder)
                );
            end loop;

        end if;

        return segments;
    end;

end;

答案 1 :(得分:1)

我保证最后的问题:)

我开始研究你的代码并考虑工作,所以我决定插入另一个带有我最后两个十六进制显示的输入并加总它们

所以我创建广告插入这部分代码

      -- insert into entity         
      key: in std_logic_vector(3 downto 0);
      clock_50: in std_logic;

      signal input2: integer;
      signal result: integer;
      signal result1: unsigned;
      .............. -- the declaration of the 2° input is the same of the first

      Process(Clock_50)
      Begin
      if(CLOCK_50' EVENT AND CLOCK_50='1' AND KEY(0)='1') THEN
             result <= input1 + input2;
             result1 <=to_unsigned(integer((result), result1'length));
             segmentsR <= unsigned_to_seven_segment(Value => unsigned(result1), number_of_digits =>2, value_is_bcd =>false);
      HEX1 <= segmentsR(13 downto 7);
      HEX0 <= segmentsR(6 downto 0);
  End if;
  End Process;

有一个错误,我找不到“近文”:“;期待”)“,或”,“.....根据我,synthax是正确的,因为在input1上,input2我已经使用了这个函数to_integer ....

最好的问候

米歇尔

答案 2 :(得分:0)

要解决3)你必须了解7段显示的工作原理,特别是字符显示。基本上,您必须实现从整数到显示器的十六进制编码的编码器。十六进制编码在显示器的数据表中提供,例如, this datasheet显示哪些显示引脚连接到哪个段。在wikipedia提供了示例性的十六进制代码。