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

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

Суть работы:

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

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

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

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

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

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

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

Симуляция программы на 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;
RSS
Нет комментариев. Ваш будет первым!
Загрузка...