Сага о светодиодах. Часть 2. Разделяй и управляй
Оглавление
*О найденных опечатках и замечаниях просим сообщить admin@fpga-systems.ru
Разделяй и управляй
Представлена следующая часть из раздела “Сага о светодиодах”
Введение
Рассмотрен этап конструирования устройства управления (УУ), задачей которого является управление источником сигналов и передатчиком этих сигналов по протоколу I2C в приёмник сигналов для их исполнения. Взаимодействие модулей с УУ осуществляется по принципу ведомый-ведущий.
Использование протокола I2C
Немного о протоколе
I2C (Inter-Integrated Circuit) — двунаправленная шина, с последовательной передачей данных и возможностью адресации до 128 устройств. Физически шина состоит из двух сигнальных линий связи, одна (SDA) служит для обмена данными и другая (SCL) используется для передачи тактового сигнала. Дальнейшее описание шины и протокола обмена данными я опущу, так как в сети существует оригинальный документ описывающий спецификацию шины THE I2C-BUS SPECIFICATION VERSION 2.1 JANUARY 2000, а также русскоязычное описание, которое можно найти, например здесь или вот здесь и во многих других местах.
Техническое задание
- Схема должна управлять переключением от 3 до 10 линий светодиодов.
- Драйвер светодиодов должен быть отдельным устройством управляемым по двунаправленной шине I2C.
В предыдущей части мы рассматривали не сложную схему управления несколькими светодиодами. Преобразуем эту схему так, чтобы она соответствовала новому ТЗ разделив её на две части,
Рис. 1. Блок схема устройства с блоком I2C
Так что теперь все устройство будет состоять из нескольких частей;
- Устройство управления
- Драйвер светодиодов
- Устройство I2C
В дальнейшем займемся конструированием того, что на рисунке обозначено как устройство управления (УУ). Это устройство управления будет состоять из нескольких модулей:
- модуль count - делитель частоты;
- модуль shift_cnt - счетчик номера линейки светодиодов;
- модуль i2c_master - ведущий приемо-передатчик.
На рисунке 2 представлено решение для левой части схемы.
Рис. 2. Блок схема устройства управления
Модуль I2C
Изобретать какой-то новый I2C модуль нет необходимости. На просторах интернета я нашел множество таких конструкций и с одной из них я и буду экспериментировать. Здесь приведена подробная информация о работе этого модуля. Ознакомившись с этой документацией можно приступить к конструированию устройства управления.
Модуль УУ
УУ должно управлять двумя устройствами;
- счетчиком линий светодиодов - модуль cnt_dev, рисунок 3;
- устройством I2C - модуль i2c_master, рисунок 4.
Рис. 3. Блок схема счетчика линий светодиодов. Порты ввода/вывода
Рис. 4. Блок схема устройства I2C. Порты ввода/вывода
УУ должно уметь управлять соответствующими сигналами на линиях этих устройств. Для управления счетчиком необходимо добавить в УУ следующие линии:
- busy_cnt - готовность счетчика к работе. Высокий уровень сигнала на линии говорит о том, что устройство занято;
- en_cnt - линия разрешения. Высокий уровень сигнала разрешает выполнить переключение счетчика;
- data_cnt - шина данных от счетчика линий светодиодов.
Для управления устройством I2C добавим следующие линии:
- busy_i2c - готовность I2C к работе. Высокий уровень сигнала свидетельствует о готовности к обслуживанию;
- en_i2c - разрешение на работу. Высокий уровень разрешает выполнить обслуживание;
- miso - шина данных, полученных из линии;
- mosi - шина данных, подготовленных для передачи;
- rw - переключатель режима приема/передачи.
Также понадобятся общие сигналы управления:
- CLK - линия тактового сигнала;
- RST - линия сигнала сброса;
- main_clk - линия основного синхронизирующего сигнала;
- rst_i2c - линия сигнала сброса для устройства I2C.
В результате получим общее устройство управления как на рисунке 5.
Рис. 5. Блок схема УУ. Порты ввода вывода
Описание работы УУ
Как отмечалось выше, сигнал o_busy - в состоянии 1 говорит о том, что I2C занят транзакцией, и надо ожидать, пока этот сигнал установится в 0, чтобы начать следующую транзакцию. В паре с этим сигналом, работает сигнал i_enable, который при активном высоком уровне разрешает начать новую транзакцию, если мастер не занят.
Для счетчика линий светодиодов Высокий уровень сигнала enable (EN) в модуле shift_cnt при низком уровне busy активирует этот модуль разрешая изменение состояния счетчика shift_cnt. Линия busy с высоким уровнем говорит о том, что устройство занято.
УУ должно учитывать состояние этих сигналов в следующих модулях и правильно их обрабатывать.
- модуль счетчика светодиодов (cnt_dev);
- модуль I2C.
Взаимодействие для обмена данными с этими модулями построим по схеме master-slave или ведомый-ведущий. Тогда общее устройство управления (УУ) будет ведущим, а счетчик светодиодов и I2C будут ведомыми, как на рисунке 6.
Рис. 6. Функциональная схема УУ по схеме ведомый-ведущий
Взаимодействие мастера с ведомым устройством будет осуществляться следующим образом.
- Мастер запрашивает сигнал busy от подчиненного устройства, и как только busy станет низким, мастер устанавливает сигнал enable в высокий уровень.
- Мастер запрашивает и получает данные от подчиненного устройства, либо устанавливает данные для подчиненного устройства.
- Затем, мастер снова запрашивает сигнал busy и как только он станет высоким, мастер устанавливает низкий уровень сигнала enable.
- И, когда busy станет снова низким, это будет свидетельствовать об окончании транзакции.
Таким образом пара сигналов busy/enable проходит следующий цикл:
- 10 ведомое устройство готово к выполнению транзакции;
- 01 ведомое устройство свободно, начало транзакции - получение либо передача данных;
- 10 освобождение ведомого устройства;
- 00 окончание транзакции;
Таким образом устройство управления взаимодействует с устройством I2C. Аналогичным образом устройство управления будет взаимодействовать с УУС.
Конструкция модуля cnt_dev
Доработаем модуль счетчика так, чтобы модуль мог участвовать в цикле обмена данными с ведущим устройством. Для этого добавим в модуль shift_cnt сигнал busy и сигнал enable и обеспечим их работу в соответствии с выше указанными требованиями,
Листинг 2.1. Модуль счетчика линий светодиодов, доработанный
|
Теперь счетчик будет переключаться только при наличии сигнала enable. Соберем счетчик и генератор в один модуль cnt_dev.
Листинг 2.2. Сборочный модуль счетчика светодиодов
|
Конструкция модуля УУ
Так как в модуле i2c_master уже есть все необходимые сигналы, то можно приступить к конструированию модуля УУ (ctl_dev). Блок схема представлена на рисунке 7.
Рис. 7. Блок схема УУ со счетчиком и приёмо-передатчиком.
Этот модуль предназначен для управления модулями cnt_dev и i2c_master. Он должен иметь необходимые для этой задачи входные и выходные сигналы. Следующий листинг описывает спецификацию портов ввода вывода.
Листинг 2.3. Часть модуля УУ. Порты ввода вывода
|
Работа блока always, цикл передатчикa
Основная задача УУ состоит в том, чтобы получить байт данных от счетчика линий светодиодов с номером линии и отдать этот байт в устройство I2C для последующей передачи в драйвер светодиода. Это показано в следующем листинге.
Листинг 2.4. Часть модуля УУ. Шаг 2:
|
Если счетчик линий светодиодов не занят (busy_cnt == 0), то включаем режим передачи, запрашиваем номер линии светодиодов, и отдаем его на передачу.
Листинг 2.5. Часть модуля УУ. Шаг 3:
|
Проверяем, если i2c_mester не занят (busy_i2c == 0), то активируем передачу сигналом en_i2c переводя его на высокий уровень.
Листинг 2.6. Часть модуля УУ. Шаг 4:
|
Освобождаем i2c_master переводя en_i2c в низкий уровень.
Листинг 2.7. Часть модуля УУ. Шаг 5:
|
И ожидаем освобождение i2c_master (низкий уровень busy_i2c). Это свидетельствует об окончании цикла передачи. После этого можем начать цикл приема.
Работа блока always, цикл приёма
Листинг 2.8. Часть модуля УУ. Цикл приема данных
|
Работа блока always, обработка ошибок
Листинг 2.9. Часть модуля УУ. Обработка ошибок
|
Если отправленные данные и принятые данные совпадают, то можно перейти к новому циклу передачи приёма данных. Этот цикл будет выполняться все время пока устройство включено.
Полная сборка устройства
Соберём всё устройства в один модуль top_dev, листинг 10.
Листинг 2.10. Модуль верхнего уровня
|
Испытательный стенд
Для испытаний подключим модуль top_dev и к нему модуль i2c_slave. Модуль i2c_slave нужен для осуществления полного цикла приема передачи данных. Также он имитирует драйвер светодиодов.
Листинг 2.11. Испытательнвый стенд.
|
В строке repeat(4) задаем 4 полных цикла приёма передачи. И, при помощи оператора $display отслеживаем отправленные и принятые данные. Запустим стенд. Получается вот такая картинка.
|
Итоги
В этой главе было выполнено конструирование не сложного устройства управления.
- Был применён принцип разделения схемы на более простые модули и сборки из этих простых модулей более сложных конструкций.
- В управлении подчинёнными модулями был применён метод ведомый/ведущий. Это позволило упростить синхронизацию работы частей схемы и согласовать работу модулей между собой.
- При проектировании использовались различные инструменты, например, symbolator. Этот инструмент помогал еще на этапе проектирования создавать каркас модулей с отображением их портов. Это позволило спроектировать связи модулей еще до прогона всего проекта в Quartus.
- Выработал для себя правило, что все входные порты это как правило провода (wire), а выходные порты это как правило регистры (reg). Тогда модули легко соединять между собой обычными проводами, как это и делается на практике.
В следующей главе будет рассмотрено проектирование приемо-передающего модуля со стороны i2c_slave. И далее я хочу рассмотреть работу с линией связи по протоколу SPI. И далее, конечно, будет что-то далее...
Кроме того, я хотел бы увидеть конструктивные замечания в отношении данного проекта, так как мой статус в этой области "студент'' и мне еще многому предстоит научиться. Спасибо.