VHDL - 去抖按钮按下

时间:2013-01-30 00:44:56

标签: switch-statement vhdl fpga

我的代码中有以下按钮按逻辑。我曾尝试使用等待延迟对其进行去抖动,但编译器不允许这样做。我的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;

任何人都可以提供一些非常简单的示例代码,展示如何去除像我上面那样的设置吗?

3 个答案:

答案 0 :(得分:2)

好吧,如果你想一想如何用真正的电子产品做这件事,你可能会使用一个充电时间的电容器。同样的想法适用于此,只需计算出开关弹跳的时间(通常是时钟速度的函数),然后实际设置寄存器。

Simple Example With a 4-Bit Shift Register

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

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个时钟周期(你试图用等待做的事情)。

答案 1 :(得分:0)

因为等待而得到错误...等待不可合成。

我会用一个简单的计数器来做。因此,您可以通过调整计数器将相同的代码用于不同的时钟速度。

-- 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;

您的代码可能会产生另一个问题。 如果你的按钮被释放会发生什么,所以你的输入是.. key =“0000”..对,你永远不会得到你的输出。也许它可以在100次中使用99次,但是你很难找到错误。

答案 2 :(得分:0)

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

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