Видео в конце...
Тем кто не знаком с основами лучше посмотреть предыдущую статью. Мы начинаем.
Проектирование передатчика
Первым делом на ПЛИС мы создадим передатчик. С ним меньше всего проблем. Нужно лишь отправить в линию сигнал определенной формы. Никаких проблем с дребезгом и отслеживанием центральной части бит информации. Это передатчик, а принимать этот сигнал будет кто-то на другом конце.
В состоянии ожидания на линии должна быть единица. Как только есть потребность в передаче двоичного слова, то на линию необходимо выставить стартовый бит с нулевым значением. Длительность этого бита определяется скоростью передачи информации. По предварительной договоренности пусть это будет 9600 бит в секунду. Чтобы определить сколько тактов кварцевого генератора нужно ожидать окончания передачи бита, разделим частоту генератора 50 миллионов импульсов в секунду на 9600 и получим около 5208 импульсов в одном бите. Ровно столько импульсов будет необходимо поддерживать уровень сигнала пока передается один бит. Конечно же это не идеальный расчет. Нацело поделить нельзя, но такая погрешность вполне допустима, так как фрейм довольно короткий и к его концу ошибка не успеет накопиться.
После стартового бита начнем выставлять информационные биты, их длительность точно такая же. Счетчик позволит нам выдержать все временные интервалы. Количество информационных бит во фрейме это тоже результат договоренности, пусть их будет 8. По окончанию информационных бит выставляем стоп бит уровня единицы. После этого переходим в режим ожидания.
Автомат состояний
Граф автомата состояний будет выглядеть следующим образом.
В режиме ожидания разрабатываемый модуль будет находиться до тех пор, пока на его входе не появится сигнал о том, что необходимо передать данные. В этот момент данные должны уже быть выставлены на вход модуля. А дальше уже запускается автомат и ему одна дорога. Довести передачу данных до конца. В момент, когда начинает передаваться стартовый бит, нужно выставить сигнал о неготовности передавать следующую порцию информации. Это позволит другому модуля с данными притормозить с очередным байтом. После передачи бит данных выставляется стоп бит и это означает, что модуль готов к следующей отправке. Можно убрать сигнал о неготовности к передаче. На этом брифинг закончен. Пора приступать к написанию кода.
Пишем код
На вход модуля поступает тактовый сигнал, байт данных, сигнал о готовности этих данных. На выходе модуля линия передачи, сигнал о готовности передавать новую порцию информации.
Перечислим все состояния автомата: ожидание, старт бит, данные, стоп бит.
Делитель счетчика это число 5208. Оно обеспечит нужную скорость передачи бит. В регистрах state и nextState будут храниться текущее и следующее состояние автомата.
Обнулим начальные значения регистров.
По переднему фронту тактового сигнала clk присваиваем текущему состоянию автомата state следующее состояние nextState. В состоянии ожидания Idle выставляем на линию передачи tx единицу. Если данные готовы к передаче, то переходим в состояние отправки стартового бита StartBit. Иначе остаемся в ожидании. В состоянии передачи стартового бита, на линию выставляем ноль и считаем импульсы. Если досчитали до нужного количества Divider, то следующее состояние будет передача бит данных DataBit и обнуляем счетчик импульсов. Пока не досчитали остаемся в этом состоянии. При передаче бит данных продолжаем ожидать временные интервалы отсчитывая импульсы. Если посчитали сколько нужно, сбрасываем счетчик и начинаем отсчитывать информационные биты bitCount. Как только их будет 8, следующее состояние StopBit. Сбросим счетчик бит. Если импульсы пришли еще не в полном количестве, то на линии передачи удерживаем бит данных. Порядок отправки от младших к старшим. Счетчик bitCount как раз помогает взять со входной шины данных нужный бит.
В состоянии StopBit выставляем на линию данных tx единицу. Сигнал о готовности к новой передаче данных выставляем в единицу и считаем импульсы для того, чтобы выдержать необходимую длину бита. Как только подождали окончания, следующим состоянием будет ожидание Idle. Сбрасываем счетчик импульсов.
Сразу напишем тестовый модуль. У него нет ни входов ни выходов. Внутри регистры и провода для связи с разработанным модулем передачи данных.
Вписываем модуль передатчика RS232Send и соединяем его с внутренними проводами и регистрами. Создаем бесконечный тактовый сигнал. Начальные состояние регистров не все нулевые. В качестве данных на вход модуля выставляем определенный байт, и еще сигнал о его готовности. Все. Модуль тестирования закончен.
Тест модуля
Давайте посмотрим что у нас получилось.
На шине данных data нужное число выставлено, сигнал о готовности dataReady также выставлен. Это сразу переводит модуль в состояние передачи стартового бита. Начиная с младшего бита данные выставляются на линию передачи tx и при этом работает счетчик этих бит bitCount. Единица и пятерка прошли на отправку, за ними стоп бит вместе с сигналом о готовности к новой передаче данных rts. Далее все повторится.
Теперь создадим еще один модуль. Его назначением будет избавить нас от работы по ручному выставлению на вход передатчика байта данных и сигнала о его готовности. Просто завернем передатчик в обертку.
Дадим ему все что он просит. Тактовый сигнал направим от кварцевого генератора и оставим на выходе одну линию передачи. В шину данных направим ASCII код заглавной буквы Z. Сигнал о готовности единица. Подключаем передатчик. Это все.
Это на самом деле пока все. Чтобы эти данные принять на компьютере нужно еще написать программу, а в этом деле тоже немало загадочных вопросов, на которые нужны ответы.
Видео-обзор с канала YouTube
Исходный код
Поддержите статью лайком если понравилось и подпишитесь чтобы ничего не пропускать.