键盘编码器为啥有 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 个状态?的主要内容,如果未能解决你的问题,请参考以下文章