Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Антидребезг контакта.
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
Iptash
Здравствуйте все.
Есть входной сигнал с плохим фронтом, поэтому происходит дребезг. Написал антидребезговый блок, так в принципе работает не плохо,
но иногда при включении стопорится, потому что видимо dreb и ndreb не обнуляются и соответственно сигнал zap
который я дальше использую не работает. Алгоритм такой. Приходит внешний сигнал IN, включается счетчик dreb и
пока не досчитает до 1000 zap будет вкл. тем самым исключая ложное срабатывание zap .
Но код какой то кривой и задний фронт вроде не коректно отрабатывает. Подскажите пожалуйста как это лучше сделать или может подправите?
Код
always @ (posedge clock1) begin
  if(IN) begin // внешний сигнал
    if(dreb == 0) begin
     zap <= 1'b1; // сигнал после фильтрации, используется дальше
     ndreb <= 0;
    end
    
  end
  
   if(zap)
    dreb <= dreb + 1'b1;
  
   if(dreb > 1000) begin
    zap <= 1'b0;  
   end
  
   if(!IN) begin
    if(ndreb == 0) begin
     nzap <= 1'b1;
     dreb <= 0;
    end
    
    end
   if(nzap)
    ndreb <= ndreb + 1'b1;
   if(ndreb > 1000) begin
    nzap <= 1'b0;      
   end
end
sazh
Цитата(Iptash @ Jul 22 2011, 20:59) *
Написал антидребезговый блок, так в принципе работает не плохо,
но иногда при включении стопорится,


Если задний фронт должен отрабатывать, в минус наверно надо считать.
Для примера.
Iptash
Цитата(sazh @ Jul 23 2011, 10:04) *
Если задний фронт должен отрабатывать, в минус наверно надо считать.
Для примера.

Да, действительно. Спасибо.
Serhiy_UA
Цитата(Iptash @ Jul 22 2011, 20:59) *
Подскажите пожалуйста как это лучше сделать...

Подойдет сдвиговый регистр,например на 16 разрядов, и небольшая FSM на несколько состояний.
Подбирается тактовая частота для FSM, и внутри FSM тактируется сдвиговый регистр, на младший разряд которого подается входной сигнал.
Когда сигнала нет, и он нулевой, то в регистре будет 16'h0000. Когда в регистре будет 16'h7fff, то переходной процесс с дребезгом уже закончился. Все остальные комбинации регистра игнорируются. FSM контролирует только эти два состояния регистра и что-то делает, когда в регистре появится код 16'h7fff.
Важно правильно подобрать тактовую частоту.
Timmy
Цитата(Iptash @ Jul 22 2011, 21:59) *
Есть входной сигнал с плохим фронтом, поэтому происходит дребезг. Написал антидребезговый блок, так в принципе работает не плохо,
но иногда при включении стопорится, потому что видимо dreb и ndreb не обнуляются и соответственно сигнал zap

Я использую вот такой антидребезг:
Код
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity deglitch is
    generic(count:integer:=100);
    port(
        clk, rst, ce:std_logic;
        d:std_logic;
        q:out std_logic
    );
end entity;

architecture rtl of deglitch is
signal cnt:integer range 1-count to 0;
signal sig0, sig1, sig2:std_logic;
begin
process(clk,rst) is begin
if rst = '1' then
    cnt <= 0; sig0<='0'; sig1<='0'; sig2<='0';
elsif rising_edge(clk) then
    sig0 <= d; sig1 <= sig0; sig2 <= sig1; --eliminate metastability
    if sig2 = '1' then
        cnt <= 1-count;
    end if;
    if cnt < 0 and ce = '1' then
        cnt <= cnt+1;
    end if;
end if;
end process;
q <= '1' when cnt < 0 else '0';
end rtl;

Обратите внимание, как делать эффективный счётчик(всё будет работать на очень высокой тактовой частоте).
Сигнал CE позволяет уменьшить разрядность счётчиков в каждой из антидребезжалок, подключив их к дополнительному общему счётчику.

UPD: очень полезно публиковать исходникиsm.gif, так как изначально я перезапускал счётчик по фронту, а надо по уровню. Иначе он будет давать второй ложный фронт на дребезге на отпускании кнопки. Странно, что не заметил, правда я с этим только слегка игрался на evaluation board.
Ethereal
Цитата(Iptash @ Jul 22 2011, 21:59) *
Здравствуйте все.
Есть входной сигнал с плохим фронтом, поэтому происходит дребезг. Написал антидребезговый блок, так в принципе работает не плохо,
но иногда при включении стопорится,

Внешних (для ПЛИС) сигналов в коде быть не должно. In нужно пропустить через >=2 последовательных регистра (в качестве примера смотрите код Timmy), и уже этот сигнал использовать в логике подавления. Иначе при попадании клока на фронт входного сигнала модуль может застопориться даже при нормальном коде.
Iptash
Цитата(Ethereal @ Jul 29 2011, 18:05) *
Внешних (для ПЛИС) сигналов в коде быть не должно. In нужно пропустить через >=2 последовательных регистра (в качестве примера смотрите код Timmy), и уже этот сигнал использовать в логике подавления. Иначе при попадании клока на фронт входного сигнала модуль может застопориться даже при нормальном коде.

Реакция на входной сигнал IN должно быть с точностью в один такт clock1 который воздействует на zap который защелкивается допустим на 1000тактов.
Эта часть работает прикрасно, у меня были проблемы с задним фронтом и взведением все в исходное. Это я тоже решил, сейчас блок антидребезга
работает очень хорошо и обрабатывает самые плохие фронты.
Спасибо.
privet
если речь идет о дребезге контакта кнопочки, то не проще просто опрашивать ее редко?
Если надежный контакт устанавливается, скажем, 1мс, то тогда опрашивать можно, например, с периодом 10мс.
Victor®
Цитата(privet @ Aug 1 2011, 09:57) *
если речь идет о дребезге контакта кнопочки, то не проще просто опрашивать ее редко?
Если надежный контакт устанавливается, скажем, 1мс, то тогда опрашивать можно, например, с периодом 10мс.


имея вероятность 10% напороться на грабли.
privet
Цитата(Victor® @ Aug 1 2011, 11:40) *
имея вероятность 10% напороться на грабли.

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

11111111111111111111111111111111110110101110101100000000000000000000000000
--------не нажата--------------->|<--дребезг--->|<----------кнопка нажата
__^____________________^____________________^____________________^_______
редкий опрос


ИМНО, период опроса кнопки просто должен быть много больше длительности дребезга.
Даже если ОДИН момент опроса попадет внутрь интервала с дребезгом - это нормально.
При этом, что будет считано? Ноль или единица? - это не важно.
Если момент опроса в попадает в интервал дребезга и читается 0, то считаем, что нажали кнопку. Ну и правда, ведь нажали? Значение входа сейчас установится и будет стабильный ноль.
Если попали в интервал дребезга и считали 1, тоже нормально, считаем, что кнопка не нажата (ну и в самом деле - нажали не очень хорошо - контакт плохой). Уже следующий poll даст стабильный 0 и тогда уж точно определим нажатие кнопки.
При таком подходе точность определения момента нажатия определяется периодом опроса, но в большинстве случаев с кнопками это вполне приемлимо.
Всякие альтернативные методы в принципе тоже имеют свой "период фильтрации", только другие методы сложнее в реализации и требуют больше логики.
Iptash
Цитата(privet @ Aug 1 2011, 10:57) *
если речь идет о дребезге контакта кнопочки, то не проще просто опрашивать ее редко?
Если надежный контакт устанавливается, скажем, 1мс, то тогда опрашивать можно, например, с периодом 10мс.

Я его не опрашиваю, он же у меня срабатывает по posedge в always. Это не кнопка, а выход компаратора.
Victor®
Цитата(Iptash @ Aug 1 2011, 12:27) *
Я его не опрашиваю, он же у меня срабатывает по posedge в always. Это не кнопка, а выход компаратора.


кстати, а чего это компаратор дребезжит-то?
Iptash
Цитата(Victor® @ Aug 1 2011, 13:50) *
кстати, а чего это компаратор дребезжит-то?

Осциллографом смотрел, передний фронт на вых. компаратора где то 200нс от 0 -> 3,3в.. А быстродействие MAX II 200мгц, я фронт смотрел, задержка
распространения ~5нс.. Видимо несколько раз MAX II воспринимает вых. компаратора как 1 и 0, наверное все же шумы тоже есть. Блок антидребезга
поставил, работает идеально.
Victor®
Цитата(Iptash @ Aug 1 2011, 16:57) *
Осциллографом смотрел, передний фронт на вых. компаратора где то 200нс от 0 -> 3,3в.. А быстродействие MAX II 200мгц, я фронт смотрел, задержка
распространения ~5нс.. Видимо несколько раз MAX II воспринимает вых. компаратора как 1 и 0, наверное все же шумы тоже есть. Блок антидребезга
поставил, работает идеально.


Так надо решать источник проблемы, а не следствие.
Что за компаратор? С гистерезисом?
По-скоростнее не думали компаратор взять?
Iptash
Цитата(Victor® @ Aug 1 2011, 18:22) *
Так надо решать источник проблемы, а не следствие.
Что за компаратор? С гистерезисом?
По-скоростнее не думали компаратор взять?

Компаратор LM211, резистор в ПОС стоит, поскоростнее AD8561 должны вот вот подойти. Но в принципе и с LM211 не плохо работает. По даташиту у
LM211 задержка распространения как раз 200нс.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.