1

我的代码中有以下按钮按下逻辑。我尝试过使用等待延迟对其进行去抖动,但编译器不允许这样做。我的 FPGA 上有四个按钮,下面的“键”数组反映了这些按钮:

process(clock)
        begin
            if rising_edge(clock) then
                if(key(3)/='1' or key(2)/='1' or key(1)/='1' or key(0)/='1') then --MY ATTEMPT AT DEBOUNCING
                    wait for 200 ns; ----MY ATTEMPT AT DEBOUNCING
                    if (key(3)='1' and key(2)='1' and key(1)='0' and last_key_state="1111" and key(0)='1') then
                        ...
                    elsif (key(3)='1' and key(2)='1' and key(1)='1' and key(0)='0' and last_key_state="1111") then  
                        ...
                    elsif (key(3)='0' and key(2)='1' and key(1)='1' and key(0)='1' and last_key_state="1111") then
                        ...
                    elsif (key(3)='1' and key(2)='0' and key(1)='1' and key(0)='1' and last_key_state="1111") then
                        ...
                    end if;
                    last_key_state<=key;
                end if;
            end if;
    end process;

谁能给出一些非常简单的示例代码来展示我如何像上面的设置那样去抖动?

4

3 回答 3

2

好吧,如果您考虑如何使用真正的电子设备来做到这一点,您可能会使用电容器......它有充电时间。同样的想法也适用于此,只需确定开关弹跳的时间(通常是时钟速度的函数),然后实际设置寄存器。

带有 4 位移位寄存器的简单示例

所以你可以把它放在你的开关和任何其他逻辑块之间

process 
  begin
   if rising_edge(clock) then --You're clock

     SHIFT_PB(2 Downto 0) <= SHIFT_PB(3 Downto 1); --Shifting each cycle
     SHIFT_PB(3) <= NOT PB; --PB is the pre-bounced signal

     If SHIFT_PB(3 Downto 0)="0000" THEN --once the bounce has settled set the debounced value
      PB_DEBOUNCED <= '1'; 
     ELSE 
      PB_DEBOUNCED <= '0'; 
   End if;
end process;

它基本上将你的信号延迟了 4 个时钟周期(你试图用等待做什么)。

于 2013-01-30T00:52:04.520 回答
1

其他人已经用计数器展示了方法......您还需要在将信号输入到计数器之前将信号同步到时钟,否则偶尔,信号会在不同的时间到达计数器的不同部分,并且计数器会错误计数.

这是否重要取决于应用程序 - 如果正确操作很重要,那么正确同步很重要!

于 2013-01-30T16:33:48.763 回答
0

You get the error because of wait ... wait is not synthesizeable.

I would do it with a simple counter. So you can use the same code for different clock speeds by adjusting the counter.

-- adjust the counter to you special needs
-- depending on how good your buttons are hardware debounced
-- you can easily think in ms
signal counter : std_logic_vector(7 DOWNTO 0) := "10000000";

process 
  begin
    if rising_edge(clock) then --You're clock
      if(key(3) = '0') or (key(2) = '0') or (key(1) = '0') or (key(0) = '0') then
        start_debouncing <= '1';
        key_vector_out <= key(3) & key(2) & key(1) & key(0); 
      end if;

      if(start_debouncing = '1') then
        key_vector_out <= "0000";
        counter <= std_logic_vector(unsigned(counter) - 1);                        
      end if;

      if(counter = "00000000") then
        counter <= "10000000";
        start_debouncing <= '0';
      end if;
end process;

Your code can produce another problem. What will happen if you button is released so your input is .. key = "0000" .. right you never get you output. Perhaps it will work 99 out of 100 times but you can get an really hard to find error.

于 2013-01-30T08:46:06.697 回答