1

コードに次のボタン押下ロジックがあります。待機遅延を使用してデバウンスを試みましたが、コンパイラはこれを許可しません。FPGAに4つのプッシュボタンがあります。これは、以下の「キー」配列が反映しています。

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

待機が原因でエラーが発生します...待機は合成できません。

簡単なカウンターでやります。したがって、カウンタを調整することで、異なるクロック速度に同じコードを使用できます。

-- 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回は機能しますが、エラーを見つけるのは非常に困難です。

于 2013-01-30T08:46:06.697 に答える