简体   繁体   English

将8位二进制转换为BCD值

[英]Converting 8 bit binary to BCD value

I have spent countless hours on this and i just finally decided i really need some help..so here i am. 我为此花费了无数小时,我终于决定我真的需要一些帮助。所以我在这里。

Basically what i am doing is taking an 8 bit input from an ADC and then converting this value to BCD to dsiplay on a seven segment board. 基本上我在做什么是从ADC接收8位输入,然后将此值转换为BCD到七段板上的dsiplay。 SO here is my code so far: 到目前为止,这是我的代码:

Library IEEE ;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use IEEE.std_logic_unsigned.all;

entity Voltage_LUT is
  Port ( scaled_value : in  unsigned(7 downto 0);
         true_value : out  STD_LOGIC_VECTOR (15 downto 0)
  );
end Voltage_LUT;

architecture Behavioral of Voltage_LUT is

  function  divide  (a : UNSIGNED; b : UNSIGNED) return unsigned is
    variable a1 : unsigned(a'length-1 downto 0):=a;
    variable b1 : unsigned(b'length-1 downto 0):=b;
    variable p1 : unsigned(b'length downto 0):= (others => '0');
    variable i : integer:=0;
  begin
    for i in 0 to b'length-1 loop
      p1(b'length-1 downto 1) := p1(b'length-2 downto 0);
      p1(0) := a1(a'length-1);
      a1(a'length-1 downto 1) := a1(a'length-2 downto 0);
      p1 := p1-b1;
      if(p1(b'length-1) ='1') then
        a1(0) :='0';
        p1 := p1+b1;
      else
        a1(0) :='1';
      end if;
    end loop;
    return a1;
  end divide;

  signal  adj: unsigned(7 downto -2);    --adjusted to max 90
  signal  max_value: unsigned(7 downto 0):= "11111111" ;    --adjusted to max 90
  signal  MSB_int: integer;   -- integer form of MSB
  signal  LSB_int: integer;    --integer form of LSB
  signal  adj2: unsigned(15 downto 0);    --converted from adjusted integer to binary
  signal  LSB: STD_LOGIC_VECTOR (3 downto 0);    --BCD for LSB
  signal  MSB: STD_LOGIC_VECTOR (3 downto 0);    --BCD for MSB
  signal  OFF: STD_LOGIC_VECTOR (3 downto 0):="1010";    --defined to be segment OFF
  signal  V: STD_LOGIC_VECTOR (3 downto 0):="1011";    --defined to be letter V

begin

  adj <= divide ( scaled_value , max_value );
  adj2 <= adj* "00001001" ;

end Behavioral;    

Essentially what i am doing is taking an 8 bit value from the ADC then expressing it as a fraction of the max value ( which is 9) and then i have to convert this to BCD... but when i am running this code i am getting an error stating: 本质上,我正在做的是从ADC取一个8位值,然后将其表示为最大值的一部分(即9),然后我必须将其转换为BCD ...但是当我运行此代码时,我是得到错误说明:

Line 38: Index value <-2> is out of range [0:2147483647] of array 第38行:索引值<-2>超出数组范围[0:2147483647]

I need the answer of the division to be a binary number (with decimals eg 11001.110) so that it would be accurate when i multiply it by 9... 我需要除法的答案是一个二进制数(带有小数,例如11001.110),这样当我将其乘以9时它将是准确的...

The offending line is: 令人反感的行是:

signal  adj: unsigned(7 downto -2);

The type unsigned does not support negative ranges. unsigned类型不支持负数范围。 If you want to treat your result as a fixed-point value with a fractional component, you have a couple choices, including: 如果要将结果作为带小数部分的定点值对待,则有两种选择,包括:

  • If you have VHDL-2008 compliant tools, you can use ieee.fixed_pkg , which includes the type ufixed , which does support negative indices, as you tried to do with unsigned . 如果您拥有兼容VHDL-2008的工具,则可以使用ieee.fixed_pkg ,其中包括ufixed类型,它确实支持负索引,就像您尝试使用unsigned

  • If you don't have VHDL-2008 compliant tools, you can always just manage the binary point virtually, ie declare: 如果您没有兼容VHDL-2008的工具,则始终可以虚拟地管理二进制点,即声明:

     signal adj: unsigned(9 downto 0); 

    With this method, you will need to do the bookkeeping manually, unfortunately. 使用这种方法,不幸的是,您将需要手动进行簿记。 Since you only appear to be doing multiplies and divides, you don't have to worry about aligning the binary point, though. 由于您似乎只是在做乘法和除法运算,因此您不必担心对齐二进制点。 Whether the value is "accurate" or not depends on how you use it in subsequent logic. 该值是否“准确”取决于您在后续逻辑中的使用方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM