|
|
  |
АНТИДРЕБЕЗГ (VHDL) |
|
|
|
Jul 25 2017, 14:52
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 13-07-17
Пользователь №: 98 133

|
Возникла проблема.Есть устройство,на выходе которого 4 светодиода (led).Они поочерёдно загораются и тухнут с частотой 1Гц . К устройству подключена кнопка (btn). Когда она нажата, сигнал должен идти на светодиоды (как показано на диаграмме). Так вот, при нажатии возникает дребезг, диоды горят хаотично, при чём даже могут гореть, когда кнопка отпущена. Код вроде простой.но никак не могу правильно этот антидребезг добавить. Заранее благодарен. ВЕРХНИЙ ФАЙЛ Код library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;
entity led_blink is port ( clk : in std_logic; -- синхросигнал btn : in std_logic; --кнопка led : out std_logic_vector(3 downto 0) --выход на светодиоды ); end led_blink;
architecture rtl of led_blink is signal ONN_OFF : std_logic := '1'; signal state : std_logic_vector(3 downto 0) := "0001"; signal divider : unsigned(23 downto 0) := (others => '0'); --делитель частоты begin main_p : process(clk) begin if (rising_edge(clk)) then if (divider < 5000000) then ---если меньше 5 млн. тактов, то счётчик наращивает 1 divider <= divider + 1; else divider <= (others => '0');--если больше,то счётчик сбрасывается в 0 if (btn = '1') then --если нажата кнопка ONN_OFF <= not(ONN_OFF);--светодиоды загораются if (ONN_OFF = '1') then state <= state(2 downto 0) & state(3); led <= state; else --если НЕ нажата led <= (others => '0');--сигнал на выход светодиодов не идёт end if; else ONN_OFF <= '1'; led <= (others => '0'); end if; end if; end if; end process; end rtl; АНТИДРЕБЕЗГ (КОРЯВЫЙ) Код library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Debouncer is Port ( clk : in std_logic; btn : in std_logic; led : out std_logic_vector(3 downto 0)); end Debouncer;
architecture Behavioral of Debouncer is signal led : std_logic_vector (3 downto 0); signal btn_cl : std_logic; begin process (clk) begin if rising_edge(clk) then if clk /= btn_cl then btn_cl <= clk; led <= (others => '0'); elsif led = "1111" then btn <= btn_cl; else led <= led + 1; end if; end if; end process; end Behavioral; Временная диаграмма работы устройства. При загрузке в устройсво, кнопка конечно же без антидребега так идеально не работает (((
|
|
|
|
|
Jul 25 2017, 15:27
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 13-07-17
Пользователь №: 98 133

|
Цитата(Flip-fl0p @ Jul 25 2017, 18:05)  спс за совет
|
|
|
|
|
Jul 26 2017, 10:58
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 13-07-17
Пользователь №: 98 133

|
Цитата(Flip-fl0p @ Jul 25 2017, 18:05)  Напишите отдельный модуль антидребезга просимулируйте его. И тогда, когда он будет работать подключайте его в проект как компонент. Компонент антидребезга добавил.Промоделировал.Но один небольшой косяк: смещение сигнала на светодиодах на 1 период (т.е. когда отпускаю кнопку, одна лампочка успевает промигнуть (( ОСНОВНАЯ СБОРКА Код library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;
entity led_blink is port ( clk : in std_logic; -- синхросигнал btn : in std_logic; --кнопка led : out std_logic_vector(3 downto 0) --выход на светодиоды ); end led_blink;
architecture rtl of led_blink is
component debounce Port ( CLOCK : IN STD_LOGIC; BATON : IN STD_LOGIC; VIHOD : OUT STD_LOGIC); end component;
signal ONN_OFF : std_logic := '1'; signal state : std_logic_vector(3 downto 0) := "0001"; signal divider : unsigned(23 downto 0) := (others => '0'); --делитель частоты signal btn_stable: std_logic; begin main_p : process(clk) begin if (rising_edge(clk)) then if (divider < 5000000) then ---если меньше 5 млн. тактов, то счётчик наращивает 1 divider <= divider + 1; else divider <= (others => '0');--если больше,то счётчик сбрасывается в 0 if (btn_stable = '1') then --если нажата кнопка ONN_OFF <= not(ONN_OFF);--светодиоды загораются if (ONN_OFF = '1') then state <= state(2 downto 0) & state(3); led <= state; else --если НЕ нажата led <= (others => '0');--сигнал на выход светодиодов не идёт end if; else ONN_OFF <= '1'; led <= (others => '0'); end if; end if; end if; end process; dd1: component debounce port map (CLOCK=>clk, BATON=>btn, VIHOD=>btn_stable); --подключение антидребезга end rtl; АНТИДРЕБЕЗГ Код LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all;
ENTITY debounce IS GENERIC( counter_size : INTEGER := 23); --РАЗРЯДНОСТЬ СЧЁТЧИКА PORT( CLOCK : IN STD_LOGIC; BATON : IN STD_LOGIC; VIHOD : OUT STD_LOGIC); END debounce;
ARCHITECTURE logic OF debounce IS SIGNAL flipflops : STD_LOGIC_VECTOR(1 DOWNTO 0); SIGNAL counter_set : STD_LOGIC; --сброс синхронизации SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size DOWNTO 0) := (OTHERS => '0'); --счётчик BEGIN
counter_set <= flipflops(0) xor flipflops(1); --запуск или сброс счётчика PROCESS(CLOCK) BEGIN IF(CLOCK'EVENT and CLOCK = '1') THEN flipflops(0) <= BATON; flipflops(1) <= flipflops(0); If(counter_set = '1') THEN counter_out <= (OTHERS => '0'); ELSIF(counter_out(counter_size) = '0') THEN counter_out <= counter_out + 1; ELSE VIHOD <= flipflops(1); END IF; END IF; END PROCESS; END logic; ВРЕМЯНКА
|
|
|
|
|
Jul 26 2017, 16:12
|

Местный
  
Группа: Участник
Сообщений: 201
Регистрация: 28-07-16
Пользователь №: 92 747

|
1. Задайтесь некоторым значением длительности дребезга и клока, все остальное вычисляйте относительно этих величин. 2. Нередко можно увидеть указания, что диапазон дребезга механических контактов 40...100 мс. 3. В приведенном примере на VHDL задаются величиной 10 мс. 4. Я в проектах закладывал меньше 10 мс. 5. В микросхемах MAX6816/MAX6817/MAX681 "CMOS Switch Debouncers" величина "Debounce Duration" составляет 20...80 мс (стр 2). http://docs-europe.electrocomponents.com/w...66b80f72acc.pdfКороче, есть из чего выбрать и над чем подумать.
--------------------
"Классики марксизма говорили, что общественно-экономическая формация меняется с изменением средств производства, которые всегда принадлежали имущему классу. И сейчас мы находимся в системе координат капитализма, когда самые передовые средства производства принадлежат уже не капиталистам. Люди, у которых нет обуви, имеют гаджеты. Сейчас создана такая информационная паутина, что вместо коллективного бессознательного можно говорить о коллективном сознании. Если иметь мозги и гаджеты, можно перевернуть весь мир. Коллективное сознание будет управлять миром! Это исторический путь, который нельзя миновать." Вячеслав Мальцев
|
|
|
|
|
Jul 26 2017, 16:19
|

Частый гость
 
Группа: Свой
Сообщений: 116
Регистрация: 13-12-12
Пользователь №: 74 831

|
А я просто использую заполнение нулями или единицами сдвигового регистра. Код signal reg_btn : std_logic_vector(7 downto 0) := x"00"; signal in_btn, out_btn : std_logic := '0';
reg_btn <= reg_btn(6 downto 0) & in_btn:
if (reg_btn = x"00") then out_btn <= '0'; elsif (reg_btn = x"FF") then out_btn <= '1'; end if;
--------------------
|
|
|
|
|
Jul 26 2017, 16:30
|
Частый гость
 
Группа: Участник
Сообщений: 135
Регистрация: 19-10-13
Пользователь №: 78 795

|
Цитата(gibson1980 @ Jul 26 2017, 19:19)  А я просто использую заполнение нулями или единицами сдвигового регистра. Обычно время фильтрации ~10 мс, а для 7-битного регистра даже на 100 МГц клоке это всего лишь 70 нс
|
|
|
|
|
Jul 26 2017, 17:10
|

Частый гость
 
Группа: Свой
Сообщений: 116
Регистрация: 13-12-12
Пользователь №: 74 831

|
Цитата(Tausinov @ Jul 26 2017, 23:30)  Обычно время фильтрации ~10 мс, а для 7-битного регистра даже на 100 МГц клоке это всего лишь 70 нс С помощью элементарного аккумулятора (acc <= acc + delta) можно задать какую угодно частоту, да и разрядность регистра подбирается по вкусу. Я привел самый простой пример, от которого можно оттолкнуться и подогнать под конкретный случай.
--------------------
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|