АнтиДРЕБЕЗГ на VHDL

 

Дребезг механических контактов – это бич практически всех начинающих разработчиков цифровой аппаратуры. И, поэтому, именно Вам, уважаемые начинающие  разработчики, в первую очередь, посвящена эта статья.

Элемент, VHDL-код которого рассмотрен в статье, необходим, если в вашем проекте имеются такие элементы, как кнопки, а так же различные механические переключатели. Как известно, именно они дают  так называемый механический звон контактов, который имеет печальное свойство превращаться в электрический какафонический сигнал (т.е. беспорядочный). Естественно, такие сигналы не мыслимы, если мы работаем со строго обозначенной логикой.

В результате этого появляются ложные срабатывания логических элементов в Вашей схеме. Это значит, что Вы нажали на кнопку один раз, а в итоге реакция устройства на это получилась такая, будто нажатий было, как минимум, тридцать. Это произошло именно в результате ДРЕБЕЗГА КОНТАКТОВ.

Дребезг после нажатия остается обычно на протяжении нескольких десятков миллисекунд. На практике считают, что этот звон можно считать завершенным (или некритичным) по прошествии 300 мс после нажатия ( в коде – xtime).

Как же избавиться от этого неприятного эффекта?

 

Под спойлером выше – это не совсем удачная ранняя попытка перенести в программу механизм работы дискретной логики, или КАК не надо делать.

А ДАЛЕЕ БУДЕТ VHDL-КОД защиты от дребезга, ПРАВИЛЬНЫЙ во ВСЕХ отношениях. КОД, который действительно даст НАДЁЖНУЮ защиту от дребезга при ЛЮБЫХ УСЛОВИЯХ. Гораздо более читабельный и понятный, ИЛИ как НАДО делать:

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity debounce is

Port ( BTN : in STD_LOGIC;
CLK : in STD_LOGIC;
Q : out STD_LOGIC := ‘0’);

end debounce;

architecture Behavioral of debounce is

constant clk_freq: integer := 150; – kHz (reference frequency)
constant xtime: integer := 300; – ms (time for clear state)
constant btn_wait: std_logic_vector (15 downto 0) := conv_std_logic_vector (xtime * clk_freq,16);
signal count: std_logic_vector (15 downto 0) := (others => ‘0’);

signal tmpCLK: std_logic;

begin

with conv_integer (count) select

tmpCLK <= BTN when 0,
CLK when others;

process (tmpCLK)

begin

if rising_edge (tmpCLK) then
Q <= ‘1’;
count <= count + 1;
if count >= btn_wait then
if BTN = ‘0’ then
Q <= ‘0’;
count <= (others => ‘0’);
else count <= count + 1;
end if;
end if;
end if;
end process;
end Behavioral;debounce

Об авторе admin

Инженер. Окончил НГТУ по специальности "Радиосвязь, телевидение и радиовещание". С 2003 г. занимаюсь разработкой электронной начинки различных радиотехнических устройств и приборов.
Запись опубликована в рубрике VHDL-коды, Все статьи с метками . Добавьте в закладки постоянную ссылку.

3 комментария на «АнтиДРЕБЕЗГ на VHDL»

  1. Тима говорит:

    Классная статья) Супер!

  2. Игорь говорит:

    Очень полезно.
    Спасибо автору.
    Жду новых статей с практическими примерами.
    ;)

  3. Петр Борисенко говорит:

    Вот что интересно.
    Во втором случае, если отпустить кнопку после завершения счета на входе снова появится дребезг, который, в свою очередь, снова запустит счетчик.

Оставить комментарий