键盘编码器为啥有 8 个状态?

Posted

技术标签:

【中文标题】键盘编码器为啥有 8 个状态?【英文标题】:Keypad encoder why with 8 states?键盘编码器为什么有 8 个状态? 【发布时间】:2014-05-06 12:48:12 【问题描述】:

我需要在 vhdl 中编写一个键盘编码器。我想用 4 个州来实现。在 columnn1 扫描 row1、row2、row2、row4 时。在我看来,这样的 4 个状态应该足够了,但是我从互联网上找到的一个例子使它有 8 个状态:

key_scanner_sm : process (clk)
  begin  -- process key_scanner
    if clk'event and clk = '1' then

      if state_inc = '1' then

        -- reset scan_complete
        scan_complete <= '0';

        case key_state is

          when pulse_row_1 =>
            key_read  <= (others => '0');
            key_row   <= "0001";
            key_state <= read_row_1;

          when read_row_1 =>
            case key_col is
              when "0001" => key_read <= X"31";  -- 1
              when "0010" => key_read <= X"32";  -- 2
              when "0100" => key_read <= X"33";  -- 3
              when "1000" => key_read <= X"41";  -- A
              when others => null;
            end case;
            key_state <= pulse_row_2;

          when pulse_row_2 =>
            key_row   <= "0010";
            key_state <= read_row_2;

          when read_row_2 =>
            case key_col is
              when "0001" => key_read <= X"34";  -- 4
              when "0010" => key_read <= X"35";  -- 5
              when "0100" => key_read <= X"36";  -- 6
              when "1000" => key_read <= X"42";  -- B
              when others => null;
            end case;
            key_state <= pulse_row_3;

          when pulse_row_3 =>
            key_row   <= "0100";
            key_state <= read_row_3;

          when read_row_3 =>
            case key_col is
              when "0001" => key_read <= X"37";  -- 7
              when "0010" => key_read <= X"38";  -- 8
              when "0100" => key_read <= X"39";  -- 9
              when "1000" => key_read <= X"43";  -- C
              when others => null;
            end case;
            key_state <= pulse_row_4;

          when pulse_row_4 =>
            key_row   <= "1000";
            key_state <= read_row_4;

          when read_row_4 =>
            case key_col is
              when "0001" => key_read <= X"2A";  -- *
              when "0010" => key_read <= X"30";  -- 0
              when "0100" => key_read <= X"23";  -- #
              when "1000" => key_read <= X"44";  -- D
              when others => null;
            end case;
            key_state     <= pulse_row_1;
            scan_complete <= '1';

          when others => null;
        end case;

      end if;
    end if;
  end process key_scanner_sm;

这背后有什么好的原因吗,有人知道吗?

【问题讨论】:

【参考方案1】:

您提供的示例需要额外的状态,因为它是作为单个 case 语句实现的。对key_row 的赋值需要一个额外的循环才能生效,然后才能读取key_col。由于这是一个简单的循环扫描,因此可以通过从前面的 read_row_n 状态分配 key_row 的下一个值来消除 pulse_row_n 状态

【讨论】:

所以我们可以简单地在 4 个状态下写这个,我只是不明白为什么编码器会在 8 个状态下这样做?为什么要让它变得更复杂?我正在寻找这背后的一个很好的理由,是吗?例如,为了防止出现按下 2 个按钮等情况? 他们没有意识到修剪某些州的机会。您在网上看到的大多数 VHDL 代码质量都很差到中等。它并不总是代表最佳实践。在这种情况下,浪费周期无关紧要,因为这是一小部分逻辑并且对于人类交互来说足够快。您需要注意的是实施过滤器来消除矩阵输入的抖动,以避免记录来自弹性按钮的多次按下。您还需要将key_col 输入同步到您的时钟域,然后再将外部信号直接馈送到去抖滤波器。 要避免的一个例子是用于同步进程的 VHDL-87 样式 clock'event 和 clock ='1' 样板。您应该使用 VHDL-93rising_edge 函数,因为它内部调用 to_X01 以在测试之前对时钟信号执行强度降低。这更具可读性,并且对于时钟可能是“H”或“L”的模拟情况下的正确行为很重要。由于编写不当、过时的教学材料,许多现代 VHDL 仍然以旧方式编码。当我在不到 15 年的代码中看到 VHDL-87 时,我怀疑它的质量。 正确的去抖非常重要,我已经在这里提出了赏金问题,如果你能帮助我,我会很高兴:***.com/questions/23434772/… 你需要在设计中保留reset。请参阅my comments on this 了解更多原因。如果您不制作生产硬件,则可以使用外部开关来控制复位,否则请考虑使用生成内部复位的建议。

以上是关于键盘编码器为啥有 8 个状态?的主要内容,如果未能解决你的问题,请参考以下文章

常用编码学习

asciiunicodeutfgb等编码详解

字符编码

python字符编码

python之字符编码

字符编码进化论