Подавление влияния дребезга контактов на ПЛИС

Пример программы на языке VDHL для ПЛИС, которая устраняет влияние дребезга контактов путем выполнения специального алгоритма (его использовали при обучении в моём универе).

Суть работы:

  • опрос происходит 50 раз в секунду (то есть каждые 20 мс)
  • создается некая переменная (удобно использовать имя вывода к которому подключена кнопка)
  • когда кнопка нажата, то к переменной добавляется единица, если не нажата, то ей присваивается ноль
  • когда значение переменной достигает 4 (то есть 4*20мс = 200 мс 80 мс (Исправлено от 23.09.2025) кнопка была нажата, а дребезг происходит меньшее время), то выполняем что нужно

Что можно изменить:

  • опрос может происходить 30-60 раз в секунду (то есть каждые 33.3 - 16.6 мс)
  • количество подтверждений также может быть 3-6 раз
  • можно также смещать биты

Что вообще происходит в программе

Здесь создается ШИМ-сигнал (код взят с хабра), а его ширина импульса (значение porog) прибавляется на 10% по нажатию тактовой кнопки (её то контакты и дребезжат), причем при достижении 90% коэффициент заполнения опять становится 10%.

Симуляция работы

В третье строке отображается логический уровень на кнопке. Пока высокий уровень (нажата), то увеличивается значение в porog, причём каждые 200 мс 80 мс (Исправлено от 23.09.2025), ну а когда низкий уровень (не нажата), ничего не происходит. В железе это всё прекрасно работает, проверено.

Симуляция программы на VDHL для устранения влияния дребезга контактов кнопки

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

Дребезг контактов не будет влиять на работу

Весь код программы

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Goon is Port ( clk : in STD_LOGIC; -- Входной тактовый вывод pwm : out STD_LOGIC; -- Вывод для вывода сигнала button : in STD_LOGIC -- Вывод для кнопки (подтянута к минусу) ); end Goon; architecture Behavioral of Goon is ---------------------------- Переменные для ШИМ-сигнала -------------------------- constant clk_freq : integer := 100_000_000; -- частота кварца constant pwm_freq : integer := 25_000; -- частота ШИМ constant max_count : integer := clk_freq / pwm_freq; -- разрядность ШИМ signal count: integer range 0 to max_count := 0; -- счетчик делителя частоты signal porog: integer := max_count / 10; -- ширина импульса логической единицы ---------------------------------------------------------------------------------- ---------------------------- Переменные для дребезга ---------------------------- signal low_frequency : std_logic_vector(20 downto 0) := (others => '0'); signal count_bounce : std_logic_vector(7 downto 0) := (others => '0'); ------------------------------------------------------------------------- begin ----------------------- Собственно процесс генерирования ШИМ-сигнала------------ process(clk) begin if rising_edge(clk) then if count = max_count then count <= 0; else count <= count + 1; end if; end if; end process; led1 <= '1' when count < porog else '0'; ------------------------------------------------------------------------------ --------------------------Дребезг----------------------------- process(clk) begin if rising_edge(clk) then low_frequency <= low_frequency + 1; if low_frequency = 2000000 then low_frequency <= (others => '0'); if button = '1' then count_bounce <= count_bounce + 1; if count_bounce = 4 then count_bounce <= (others => '0'); porog <= porog + max_count/10; if porog >= max_count*9/10 then porog <= max_count/10; end if; end if; else count_bounce <= (others => '0'); end if; end if; end if; end process; --------------------------------------------------------------- end Behavioral;
4190
RSS
S-trace
22:05

> 4*20мс = 200 мс 

4*20 == 80

14:18

Спасибо, исправил.

Загрузка...