【问题标题】:How do I combine incoming data and character in VHDL?如何在 VHDL 中组合传入的数据和字符?
【发布时间】:2015-10-04 14:46:34
【问题描述】:

我想用 VHDL 驱动一个 4x16 LCD 显示器。第一行应该说“FREQ:000 RPM”,其中的零代表传入的 8 位频率数据。对于具有不同数据(也是 8 位)的下一行也是如此。我的VHDL代码如下:

-- 16 Characters
subtype string16_type is string(1 to 16);
-- 4 string of 16 characters
type message4x16_type is array(1 to 4) of string16_type;
-- Define messages displayed
constant message_home:  message4x16_type := (    --1234567890123456
                                             1 => "FREE MODE       ",
                                             2 => "PARCOURS        ",
                                             3 => "- - - - - - - - ",
                                             4 => " - - - - - - - -");
constant message_info:  message4x16_type := (    --1234567890123456
                                             1 => "FREQ:  000 RPM  ",
                                             2 => "SPEED: 000 KM/H ",
                                             3 => "DIST:  000 KM   ",
                                             4 => "MORE INFO       ");
-- Character amount in  line
signal character_counter: integer range 1 to 16;
-- Line amount on LCD
signal line_counter     : integer range 1 to 4;

然后跟随一个状态机,状态 write_char 部分看起来像这样:

if msg_select = '0' then
    aline := message_home(line_counter);
elsif msg_select = '1' then
    aline := message_info(line_counter);
end if;
data <= std_logic_vector(to_unsigned(character'pos(aline(character_counter)),8));

一切都以这种方式顺利进行,但我想不出一种将频率数据实现到消息中的方法,比如在 C 中使用 %i。我知道“记录”语句,但不确定如何在这个情况。任何其他实现数据的方法都非常受欢迎。

感谢正手。

【问题讨论】:

  • “将频率数据实现到消息中”是什么意思?将000替换为数值的ASCII字符串形式?
  • 你知道连接符号'&'吗?
  • 常量声明后不能修改其值。这建议您要么使用 4x16 显示器的随机访问功能,要么创建一个信号或可变行缓冲区字符串,可以将常量字符串复制到、编辑并随后写入显示器。符合合成条件的东西需要固定长度,这就是为什么在 VHDL 中找不到 C 字符串格式的原因。

标签: arrays vhdl message lcd


【解决方案1】:

像以前一样声明类型、常量和信号:

-- 16 characters
type lcd_line_type is array(0 to 15) of character;
-- 4 lines of 16 characters
type message4x16_type is array(0 to 3) of lcd_line_type;
-- Define messages displayed
constant message_home : message4x16_type := (
--1234567890123456
 "FREE MODE       ",
 "PARCOURS        ",
 "- - - - - - - - ",
 " - - - - - - - -"
);
constant message_info :  message4x16_type := (
--1234567890123456
 "FREQ:  000 RPM  ",
 "SPEED: 000 KM/H ",
 "DIST:  000 KM   ",
 "MORE INFO       "
);
-- Character amount in line
signal character_counter : integer range 0 to 15;
-- Line amount on LCD
signal line_counter : integer range 0 to 3;

subtype rawchar is std_logic_vector(7 downto 0);
type rawstring is array(natural range <>) of rawchar;
signal rpm : rawstring(2 downto 0);
signal kmh : rawstring(2 downto 0);

function to_rawchar(char : character) return rawchar is
begin
  return std_logic_vector(to_unsigned(character'pos(char), 8));
end function;

使用示例:

if msg_select = '0' then
  data <= to_rawchar(message_home(line_counter)(character_counter));
elsif msg_select = '1' then
  case line_counter is
    when 0 =>
      -- replace 000 by rpm(2:0)
      case character_counter is
        when 6 => data <= rpm(2);
        when 7 => data <= rpm(1);
        when 8 => data <= rpm(0);
        when others => data <= to_rawchar(message_info(0)(character_counter));
      end case;
    when 1 =>
      -- replace 000 by kmh(2:0)
      case character_counter is
        when 7 => data <= kmh(2);
        when 8 => data <= kmh(1);
        when 9 => data <= kmh(0);
        when others => data <= to_rawchar(message_info(1)(character_counter));
      end case;
    -- ...
  end case;
end if;

第一个案例测试请求的行。第二种情况会覆盖特定位置的常量值。

我另外提取了 char 到 slv 的转换成一个函数。

【讨论】:

  • 感谢一百万!这正是我想要的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-11
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多