FPGAプログラミング。 「コンタクトの跳ね返り」の現象とそれを取り除く方法の研究

FPGAVHDLの研究を続けています 。 初心者を対象としたこの記事では、「連絡先の跳ね返り」の現象を調査し、それを取り除く方法を検討します。



したがって、作業の目標:「 連絡先の跳ね返り 」の現象を調べるには、 Xilinx ISE Project Navigatorでプロジェクトを作成します。ボタンをクリックすると、レジスタの値が1増加します。





パート1。コンタクトバウンスとは何ですか?



「衝撃とは、電気および電子スイッチで発生する現象であり、安定した信号の代わりに、出力でランダムな高周波振動を生成します」 (c)ウィキペディア。

簡単に言えば、ボタンを押して放しても、すぐに目的の状態にはなりません。 しばらくの間、ボタンはそれらの間でガタガタと接触しますが、これはマイクロコントローラによって複数のパルスとして認識されます。 これらのパルスの数は数千を超えることがあります。 視覚的に、バウンスはオシログラムで見ることができ、ボタンが放された瞬間を示します。







パート2.プロジェクトの作成。



前回の記事では、ザイリンクスISE Project Navigator v12.3でのSpartan-3Eスターターキット用の新しいプロジェクトの作成について詳しく説明しました。 プロジェクトを再度作成し、たとえばdrebezg_habrと名前を付けて変更を加えます。



1. 1つのボタンと8つのLEDが必要です。 btn入力信号と8つのled出力信号をポートに追加します。

エンティティ drebezg_habr

ポート clk STD_LOGIC ;

btn STD_LOGIC ;

led STD_LOGIC_VECTOR 7 downto 0 ;

drebezg_habrを終了します


2. pin.ucfファイルに、ボタンと各LEDに対応する脚の名前を書きます。

NET "clk" LOC = "C9" ;

NET "led <0>" LOC = "F12" ;

NET "led <1>" LOC = "E12" ;

NET "led <2>" LOC = "E11" ;

NET "led <3>" LOC = "F11" ;

NET "led <4>" LOC = "C11" ;

NET "led <5>" LOC = "D11" ;

NET "led <6>" LOC = "E9" ;

NET "led <7>" LOC = "F9" ;

NET "btn" LOC = "K17" ;

NET "btn" PULLUP ;


レッグK17は、利用可能な下ボタンに対応します。



PULLUPという単語は、次のようにボタンを接続します(FPGA内)。





パート3.プログラミング。



drebezg_habr.vhdファイルに移動します。 8ビットのレジスタカウンターを作成しましょう。ボタンを1回押すと、1つずつ追加しようとします。アーキテクチャと書き込みの間に

シグナル count_led std_logic_vector 7 downto 0 ;


そして、言葉が始まった直後に、このカウンターをLEDに向けます。

led <= count_led ;


ここでのタスクは、ボタンが押されたときにcount_ledカウンターに1を追加することです。 すぐに、ボタンの前の状態を保存し、現在の状態と比較する変数を作成する決定が下されます。 これをやってみましょう:

アーキテクチャ drebezg_habrの動作



シグナル count_led std_logic_vector 7 downto 0 ;

シグナル old_btn std_logic ;



始める



プロセス clk

始める

rising_edge clk )の 場合

old_btn <= btn ;

old_btn = ' 0 ' および btn = ' 1 'の場合

count_led <= count_led + 1 ;

終了する 場合 ;

終了する 場合 ;

終了 プロセス ;



led <= count_led ;



ビヘイビア;


放送、縫製、テスト。 ダイオードは単純に完全にランダムに点滅するため、結果はまったくあなたに合わないと確信しています。 これは、old_btn = '0'およびbtn = '1'の場合、連絡先のガタガタ音によるボタンの押し下げ中に多くのイベントが発生するためです。 この現象を取り除くには、論理ユニットの明確に確立された値を待つ必要があります。 これを行うには、1ずつ増加するカウンターを開始しますが、ボタンには論理単位の値があります。 ボタンが論理ゼロの値を受け入れた場合、カウンターはゼロにリセットされます。 したがって、バウンスのためにボタンが押されている間にパルスがいくつあったとしても、btn値が論理ユニットに明確に設定され、カウンターが特定の値に達する瞬間があり、ボタンが実際にコミットされたと判断できます。 ここで、変数old_btnは必要ありません。

アーキテクチャ drebezg_habrの動作



シグナル count_led std_logic_vector 7 downto 0 ;

定数 clk_freq integer := 50 _000_000 ; -クォーツ周波数

定数 btn_wait integer := clk_freq / 4 ; -ユニットを確立するまで0.25秒待機します

シグナル 整数 範囲 0 から btn_wait := 0 ;



始める



プロセス clk

始める

rising_edge clk )の 場合

btn = ' 1 'の場合

カウント<=カウント+ 1 ;

count = btn_waitの場合

count_led <= count_led + 1 ;

カウント<= 0 ;

終了する 場合 ;

他に

カウント<= 0 ;

終了する 場合 ;

終了する 場合 ;

終了 プロセス ;



led <= count_led ;



ビヘイビア;


btn_wait値は0.25秒に選択されているため、ボタンがクランプ状態のときにcount_led値が頻繁に追加されることはありません。

アンチバウンスの別のバージョン(さらに信頼性が高い)は、btnが論理ユニットの場合にカウントを1に加算し、btnがゼロの場合にカウント1から減算します。 さらに、カウント値が0に低下した場合、ボタンが押されていないか、チャタリングが発生しています。 まあ、カウントが大切なbtn_waitにカウントされている場合、プレスがありました=)

宿題として、プロジェクトを終了することをお勧めします。ボタンを押して放した後にcount_ledを追加します。



それで、私たちは実際に「接触の跳ね返り」の現象に精通し、それを取り除くことを学びました。 この現象は、ボタン、トグルスイッチ、その他の類似のものだけでなく、RS-232などのさまざまなプロトコルでも時々見られます。

プロジェクトのソースコードはこちらです。 FPGAの習得にご成功をお祈りします!



All Articles