lyzifer 0 25 июля, 2017 Опубликовано 25 июля, 2017 · Жалоба Возникла проблема.Есть устройство,на выходе которого 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; Временная диаграмма работы устройства. При загрузке в устройсво, кнопка конечно же без антидребега так идеально не работает ((( Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 25 июля, 2017 Опубликовано 25 июля, 2017 (изменено) · Жалоба Напишите отдельный модуль антидребезга просимулируйте его. И тогда, когда он будет работать подключайте его в проект как компонент. Как написать модуль антидребега смотрите в www.google.ru. По запросу "vhdl debounce" находиться достаточно материала, чтобы его написать самостоятельно. Ну или возьмите готовый... P.S. А вообще Вам уже предлагали по Skype объяснить как это все реализовать. Изменено 25 июля, 2017 пользователем Flip-fl0p Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lyzifer 0 25 июля, 2017 Опубликовано 25 июля, 2017 · Жалоба спс за совет Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 25 июля, 2017 Опубликовано 25 июля, 2017 · Жалоба спс за совет Кстати говоря, первая же ссылка (https://eewiki.net/pages/viewpage.action?pageId=4980758) показывает готовый модуль антидребезга. Я пользуюсь практически таким-же. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 25 июля, 2017 Опубликовано 25 июля, 2017 · Жалоба Напишите отдельный модуль антидребезга просимулируйте его. И тогда, когда он будет работать подключайте его в проект как компонент. Шел в тему с этим же советом. Это хорошая практика - делать отдельный модуль, отдельно тестировать, а потом всегда использовать с уверенностью что эта конкретная часть надежна. Кроме того, подсказывая новичку: у модуля могут быть "параметры", потому что в одной задаче модуль требуется с одними, а в другой задаче - с другими. Эти числа (параметры) можно менять для каждого экземпляра такого объекта. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lyzifer 0 26 июля, 2017 Опубликовано 26 июля, 2017 · Жалоба Напишите отдельный модуль антидребезга просимулируйте его. И тогда, когда он будет работать подключайте его в проект как компонент. Компонент антидребезга добавил.Промоделировал.Но один небольшой косяк: смещение сигнала на светодиодах на 1 период (т.е. когда отпускаю кнопку, одна лампочка успевает промигнуть (( :laughing: ОСНОВНАЯ СБОРКА 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; ВРЕМЯНКА Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 26 июля, 2017 Опубликовано 26 июля, 2017 · Жалоба Если вы посмотрите внимательно на антидребезг, то увидите, что он как-бы сигнал сдвигает на время, в течении которого у Вас фильтруется дребезг. 23 разряда на анти дребезг - это сильно. Посчитайте ради интереса, сколько у вас пройдет времени когда в 23 разряде счетчика появиться единичка. Скорее всего пройдет как раз 1 секунда, из-за чего у вас и происходит "паразитное" зажигание светодиода. Время дребезга существенно меньше, чем 1 секунда. Уменьшите время фильтрации и должно всё заработать. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
backend 0 26 июля, 2017 Опубликовано 26 июля, 2017 · Жалоба 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 Короче, есть из чего выбрать и над чем подумать. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gibson1980 0 26 июля, 2017 Опубликовано 26 июля, 2017 · Жалоба А я просто использую заполнение нулями или единицами сдвигового регистра. 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; Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tausinov 0 26 июля, 2017 Опубликовано 26 июля, 2017 · Жалоба А я просто использую заполнение нулями или единицами сдвигового регистра. Обычно время фильтрации ~10 мс, а для 7-битного регистра даже на 100 МГц клоке это всего лишь 70 нс Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gibson1980 0 26 июля, 2017 Опубликовано 26 июля, 2017 · Жалоба Обычно время фильтрации ~10 мс, а для 7-битного регистра даже на 100 МГц клоке это всего лишь 70 нс С помощью элементарного аккумулятора (acc <= acc + delta) можно задать какую угодно частоту, да и разрядность регистра подбирается по вкусу. Я привел самый простой пример, от которого можно оттолкнуться и подогнать под конкретный случай. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_sda 0 27 июля, 2017 Опубликовано 27 июля, 2017 · Жалоба 4. Я в проектах закладывал меньше 10 мс. Это зависит от качества кнопок. По моему многолетнему опыту - 5...50мс. Больше 50мс ни разу не приходилось устанавливать. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться