Приветствую в своём блоге, где я стремлюсь к запуску Linux на своей платке с Altera Cyclone IV. Это уже 4-я часть блога, и сегодня я продолжу осваивать Verilog, заодно приступлю к созданию дорогого и неудобного кухонного таймера.
Цель создать кухонный таймер появилась не просто так, а после просмотра вот этого видео:
И в нём рассматривается 4-х позиционный семисегментный индикатор. А так-же на него выводится пара цифр.
Но это было скучно, поэтому решил расширить задачу. В конце концов, основная цель, решаемая мною вместе с просмотром этого видеокурса - это попрактиковаться в Verilog и усвоить несколько примеров того, как нужно проектировать схемы, а как не нужно.
Потому и таймер. Кроме индикатора, понадобится мне ещё и кнопки, которых на плате целых 4 штуки. Буду использовать их так:
- Добавить 30 секунд ко времени
- Убрать 30 секунд
- Запустить таймер/поставить на паузу.
- Остановить и сбросить таймер
Мой опыт работы с микроконтроллерами подсказывает, что раз я хочу выполнять какое-то действие на каждое нажатие кнопки, то передо мной встаёт проблема дребезга контактов. И с этой проблемой надо бороться.
А решается эта проблема так: состояние кнопки запоминается, а затем с определённой периодичностью измеряется сигнал от неё. И если на протяжении некоторого времени эти замеры дают один и тот-же, противоположенный сохранённому результат, то констатируется смена состояния.
Время, необходимое на прекращение дребезга зависит от кнопки, и может достигать аж 10 мс. (сотая часть секунды). Хотя это только отдельные образцы. Большинство кнопок укладываются в 6мс, а в среднем дребезг длится 1-2 мс.
Итоговый, модуль устранения дребезга выглядит так.
Длина последовательности last в битах, помноженная на время периода сигнала clk как раз и дадут продолжительность периода, в течении которого производятся замеры состояния кнопки перед её переключением. Я собираюсь тактировать модуль 512гц, длина last - 3 бита, итоговый период замера: 6мс. А поскольку самих замеров целых 3 штуки, и смотрю я на все, то ложные срабатывания крайне маловероятны. Обратите внимание, что модуль наружу выдаёт не состояние кнопки, а сигнал pos, длительность этого сигнала составляет всегда ровно 1 такт. Называется подобные сигналы стробами. Появление такого строба обозначает, что на кнопку нажали.
И раз я решил тактировать модуль дребезга 512 гц, то эти 512гц нужно откуда-то получить. На помощь приходит счётчик, с периодом работы равным: 48000000 / 512 = 93750. На этот раз ровно, а не приблизительно.
Значит, добавлю в проект делитель частоты.
Модуль невероятно прост, так что даже не удивительно, что работает хорошо и чётко.
Ну и последнее, что я сделаю в рамках сегодняшней статьи - создам сам дисплейный модуль. Отображать он будет 16 битное значение в 16-ричном виде. Если применить немного фантазии, то 16-ричное представление может быть отображено и на 7-сегментном индикаторе. Получится как то так
И пусть непосредственно для кухонного таймера, все эти abcdef не нужны, но я сделаю и их сразу. Мешать они не станут.
Дисплейный модуль получился таким.
И пусть сток кода в нём не так мало, он до неприличия прост. Ну и в завершении - диаграмма его работы:
Вот только сам контроллер таймера я решил оставить на следующую статью. Он оказался не таким уж простым, как всё то, что я понасоздавал сегодня.
До новых встреч, с вами был мой блог, в котором я планирую сообщать о своих достижениях как можно чаще (в идеале - ежедневно)