Страница 1 из 2
Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вс фев 12, 2012 23:46:42
ukr-sasha
Здравствуйте.
По мотивам темы в одном из блогов "Простенькие примеры на VHDL" на
easyelectronics, пытаюсь выполнить мигалку светодиодом. Логика ее работы такова: в зависимости от состояния переключателя ( ноль или единица) светодиод должен мигать с частотой входящего сигнала от кварца или в десять раз медленнее. Но какую то ошибку все же я не вижу, так как в самом устройстве уже, корректно работает только ветка с условием "1 на входе", а если "0", то светодиод чуть светится, причем непрерывно.
Направьте пожалуйста на путь истинный.

П.С. Код прилагаю.
Код: Выделить всё
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
entity Migalka is
port( Knopka, CLK: in std_logic; -- кнопка и частота
Led : out std_logic); -- выход на светодиод
end Migalka;
architecture Behavioral of Migalka is
signal counter, Knopka_temp : std_logic_vector(3 downto 0):= (others => '0');
signal Led_temp, res : std_logic := '0'; -- сигнал состояния кнопки
begin
-- count : process(Knopka) -- процесс проверки состояния кнопки
-- begin
-- Knopka_temp<=(others => '0');
-- if (Knopka='1') then Knopka_temp<=Knopka_temp+1;
-- else Knopka_temp<=Knopka_temp+10;
-- end if;
--
-- end process;
count1 : process(CLK,res) -- первый процесс счетчика
begin
if(res = '1') then -- обнуляем счетчик, когда res = 1, как видно сброс асинхронный
counter <= (others => '0');
elsif(rising_edge(CLK)) then -- здесь ждем фронта сигнала и увеличиваем на единицу значение в счетчике, если будет фронт
counter <= counter +1;
end if;
-- Knopka_temp<=(others => '0');
-- if (Knopka='1') then Knopka_temp<=Knopka_temp+1;
-- elsif (Knopka='0') then Knopka_temp<=Knopka_temp+10;
-- end if;
end process;
L : process(counter)
begin
Knopka_temp<=(others => '0');
if (Knopka='1') then Knopka_temp<=Knopka_temp+1;
elsif (Knopka='0') then Knopka_temp<=Knopka_temp+20;
end if;
if(counter = Knopka_temp) then -- проверяем достижения 'Knopka_temp' тактов
res <= '1'; -- если достигли ставим сигнал сброса
LED_temp <= not LED_temp; -- меняем значение в выдаваемого на светодиод, здесь как раз хорошо видно для чего нужен триггер
--( это реализуется на триггере, мы помним предыдущее значение и его изменяем)
else
res <= '0'; -- если еще не досчитали до 'Knopka_temp' подтверждаем отсутствие сброса
end if;
end process;
Led <= Led_temp; -- вот тут передаем значения из триггера на выход
end Behavioral;
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Пн фев 13, 2012 01:26:26
SubDia
дайте ссылку на оригинал статьи. Там ребята тоже моргали светодиодом с частотой кварца?

Это, кстати, и есть то самое Ваше "чуть светится непрерывно."
Код пока что не разбирал - пишу на verilog, пока что времени на разбор полетов не было, хочу оригинал глянуть сперва.
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Пн фев 13, 2012 10:58:19
uldemir
Не понял место у метки L:. knopka_temp постоянно увеличивается и сравнивается с counter. Это какие-то догоняшки или я что-то не понял в этой логике?
мя может ошибаться, потому как в таком стиле не пишу - обычно делаю всё более прямолинейно.
Ну и как сказал SubDia, а вы на взгляд можете отличить "частоту кварца", она не за высокая?
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Пн фев 13, 2012 22:31:26
ukr-sasha
Вот ссылка на оригинал статьи:
http://we.easyelectronics.ru/plis/prost ... -vhdl.html .
На самом деле у меня не кварц, и частота около 2Гц (2 импульса в секунду) задается 555 таймером.
Почему постоянно увеличивается? Там же перед проверкой условия, и увеличения значения сигнала, я его обнуляю. Или это не так работает? А как бы вы реализовали такой алгоритм?
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вт фев 14, 2012 08:29:30
uldemir
Мой вариант может появится позже - сейчас на работу надо бежать. Но мне почему-то кажется, что этот фрагмент задумывался как:
Код: Выделить всё
L : process(counter)
begin
Knopka_temp<=(others => '0');
if (Knopka='1') then Knopka_temp<=1;
elsif (Knopka='0') then Knopka_temp<=20;
end if;
Тогда это значение там будет стоять в соответствии с положением кнопки, а не постоянно инкрементироваться (похоже совершенно асинхронно) и случайно совпадать с counter. Но как говорят умные книги: "избегайте асинхронных схем везде, где это возможно".
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вт фев 14, 2012 10:02:22
Meteor
А таймер (555) правильную частоту генерирует?
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вт фев 14, 2012 15:45:48
ukr-sasha
Думаю правильно, так как при загрузке другого проекта, где просто мигает светодиод, все нормально. В данном случае само значение частоты не важно, так же, как и ее делители. Важно, чтобы заработал алгоритм выбора делителя частоты, в зависимости от положения входа.
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вт фев 14, 2012 15:58:17
ukr-sasha
Код: Выделить всё
L : process(counter)
begin
Knopka_temp<=(others => '0');
if (Knopka='1') then Knopka_temp<=1;
elsif (Knopka='0') then Knopka_temp<=20;
end if;
Такой вариант не компилируется.
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вт фев 14, 2012 16:42:14
uldemir
Ах да, несоответствие типов. ну тогда присвойте "10100" вместо 20 и "00001" вместо 1.
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вт фев 14, 2012 17:09:04
ukr-sasha
uldemir писал(а):Ах да, несоответствие типов. ну тогда присвойте "10100" вместо 20 и "00001" вместо 1.
Спасибо, получилось скомпилировать. Позже попробую на реальном устройстве.
Еще вопрос, асинхронная схема, почему? Не совсем понятно. Из-за того, что опрос кнопки идет не в процессе обработки сигнала CLK?
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Ср фев 15, 2012 11:09:05
uldemir
Ожидая сегодня вызовы, появилось свободное время посмотреть поближе. Мое замечание насчет метки L и присваивания вместо инкремента проблему не решит. Не заметил, что перед этим knopka_temp старательно обнуляется. Так что разницы никакой. С другой стороны, посмотрел, что говорит ISE при сборке этого проекта. Одно скажу: очень много невнятных предупреждений. Это не ошибки, но и предупреждения откидывать просто так нельзя. Post-fit симуляция при первом же такте сигнал LED объявила неопределенным - что мы и видим: "светодиод чуть светится" (причем независимо от состояния кнопки). Поведенческая симуляция, показывает, что по первому такту отрабатывает метка L:, устанавливая res в '1' и тем самым сразу вызывая изменения counter (находится в списке чувствительности) и после этого там и остается на веки вечные (во всяком случае на ближайшие 100 тактов).
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Ср фев 15, 2012 22:19:35
ukr-sasha
Спасибо за ответ, нужно осмыслить прочитанное. И все таки, было бы интересно посмотреть ваш вариант реализации алгоритма.
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Ср фев 15, 2012 22:31:00
uldemir
О. я сегодня уже настрогал целых 5кб текста. Правда, не отлаживал еще, и сегодня больше неспособен. Завтра будет длинный день, так что раньше пятницы не обещаю. Да и в пятницу не знаю, будет ли свободное время. Может кто другой поспеет. Но, вообще-то народ тащится со всяких симуляций, хотя для меня единственный критерий истины - работа в железе, но тем не менее невнятные куски обычно всё же прогоняю через симулятор. Так что рекомендую попробовать.
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Пт фев 17, 2012 21:02:38
uldemir
Ну вот вариант отлаженный. комментарии внутри.
Код: Выделить всё
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity test1 is
Port ( clk : in STD_LOGIC;
knopka : in STD_LOGIC;
led : out STD_LOGIC);
end test1;
architecture Behavioral of test1 is
signal counter : STD_LOGIC_VECTOR (3 downto 0) := (others=>'0'); -- счетчик
signal limit : STD_LOGIC_VECTOR (3 downto 0); -- переменная хранящая значение до скольки считать
signal led_status : STD_LOGIC := '0'; -- триггер светодиода
signal knopka_prev : STD_LOGIC := '0'; -- триггер запоминающий предыдущее состояние кнопки
begin
-- в зависимости от состояния кнопки загружается 0 или 9
limit <= conv_std_logic_vector(0,4) when knopka = '1' else conv_std_logic_vector(9,4);
process(clk)
begin
if (clk'event and clk='1') then -- по каждому фронту
counter <= counter + 1; -- увеличиваем счетчик
if knopka = not knopka_prev then -- если обнаружено изменение состояния кнопки
knopka_prev <= knopka; -- запоминаем новое и
counter <= (others=>'0'); -- сбрасываем счетчик. Заодно
led_status <= not led_status; -- меняем статус светодиода, чтобы предыдущий
-- период не суммировался со следующим
end if;
if (counter = limit) then -- если досчитали до нужного числа
counter <= (others=>'0'); -- сбрасываем счетчик и
led_status <= not led_status; -- меняем состояние светодиода
end if;
end if;
end process;
-- вот и всё.
led <= led_status;
end Behavioral;
Вот модуль симуляции. Можете им протестировать свою схему, только измените test1 на Migalka или как вы тот модуль обозвали
Спойлер
Код: Выделить всё
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY test_model_vhd IS
END test_model_vhd;
ARCHITECTURE behavior OF test_model_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT test1
PORT(
clk : IN std_logic;
knopka : IN std_logic;
led : OUT std_logic
);
END COMPONENT;
--Inputs
signal Knopka : std_logic := '1';
signal CLK : std_logic := '0';
--Outputs
signal Led1 : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: test1 PORT MAP (
Knopka => Knopka,
CLK => CLK,
Led => Led1
);
CLK_process :process
begin
CLK <= '1';
wait for 500 ns;
CLK <= '0';
wait for 500 ns;
end process;
-- Stimulus process
stim_proc: process
begin
wait for 15 us;
knopka <= '0';
wait for 19 us;
knopka <= '1';
wait;
end process;
END;
А вот картинка:
Имплементация заняла всего 6 макроячеек: 4 счетчик и 2 триггера - кнопки и светодиода.
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Пт фев 17, 2012 22:58:55
ukr-sasha
Преогромнейшее спасибо.
Буду разбираться. Хочу понять принцип программирования параллельных процессов. Пока мозги набекрень.
uldemirвы единственный, кто мне помог.
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Сб фев 18, 2012 09:02:56
Gudd-Head
Надеюсь сегодня спаять-таки программатор и макетку с ХС9536, так что тоже здесь буду задавать дурацкие вопросы.
uldemir, такие простыни кода всё-таки лучше оформлять во вложении — см.п.5 Правил Форума.
Gudd-Head
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вс фев 19, 2012 08:56:10
ukr-sasha
Работает безупречно.
Пытаюсь на основе вашего кода, развить идею дальше. Что получится отпишусь (или не получится

).
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вс фев 19, 2012 09:47:51
ukr-sasha
Вместо кнопки поставил переключатель на 4 состояния. Поменял код совсем чуть чуть:
Код: Выделить всё
entity EncoderFromRadiokot is
Port ( clk : in STD_LOGIC;
knopka : in STD_LOGIC_VECTOR ( 1 downto 0);
led : out STD_LOGIC);
end EncoderFromRadiokot;
architecture Behavioral of EncoderFromRadiokot is
signal counter : STD_LOGIC_VECTOR (3 downto 0) := (others=>'0'); -- счетчик
signal limit : STD_LOGIC_VECTOR (3 downto 0); -- переменная хранящая значение до скольки считать
signal led_status : STD_LOGIC := '0'; -- триггер светодиода
signal knopka_prev : STD_LOGIC_VECTOR (1 downto 0) := "00"; -- триггер запоминающий предыдущее состояние переключателя
begin
-- в зависимости от состояния переключателя загружается 0, 3, 6 или 9
limit <= conv_std_logic_vector(0,4) when knopka = "00"
else conv_std_logic_vector(3,4) when knopka = "10"
else conv_std_logic_vector(6,4) when knopka = "01"
else conv_std_logic_vector(9,4) when knopka = "11";
Это отрывок кода.
Все работает, продвигаюсь дальше...
П.С. При синтезировании пишет такое предупреждение: WARNING:Cpld - Unable to retrieve the path to the iSE Project Repository. Will use the default filename of 'EncoderFromRadiokot.ise'.
Что это значит? Не может писать в каталог с проектом?
Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вс фев 19, 2012 09:59:36
Gudd-Head
Вдогонку про 9536: я в даташите нигде не нашёл про максимальный ток по пинам VCC/GND. Так ли это, или я слепой?

Re: Мигалка светодиодом на ХС9536 - помогите новичку.
Добавлено: Вс фев 19, 2012 10:28:06
uldemir
Есть в даташитах. 8ма. Сейчас поищу где конкретно.
p.s. 8ma Это для XL серии. Для просто 9536 - 24ма. Прямо на первом листе ds064.pdf где features: High-drive 24 mA outputs. и там где параметр напряжение выхода при лог.1 и 0 в test conditions эта цифра упоминается. Другого явного ограничения на выходной ток я не вижу.
p.p.s Для XL 8мА похоже втекающий ток. Вытекающий только 4мА. Но это тоже не явно, а в test conditions написано.