
したがって、作業の目標:「 連絡先の跳ね返り 」の現象を調べるには、 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の習得にご成功をお祈りします!