среда, 12 августа 2020 г.

Прием по uart на ассемблере для ATtiny2313

 Интерфейс uart (универсальный асинхронный приемник передатчик) часто используется для связи разных устройств друг с другом. Например для связи компьютера с микроконтроллером или микроконтроллера с например радиомодулем или другим микроконтроллером, модулем или микросхемой. Изучив uart микроконтроллера ATtiny2313 можно будет заменить Ардуино, в некоторых случаях, этим микроконтроллером. Чтобы изучить uart можно например поставить какую нибудь задачу например зажечь светодиод подключенный к микроконтроллеру передав ему какой либо код по uartу тогда в процессе решения этой задачи придет понимание того как использовать этот интерфейс. Светодиод, в таком случае, нельзя подключить к нулевому или первому пину порта D т.к. эти пины являются пинами uartа микроконтроллера ATtiny2313. Его можно подключить например к нулевому пину порта B


Рисунок 1 - Схема

В схему добавлены разъемы для того чтобы микроконтроллер можно было соединить с программатором чтобы зампрограммировать а потом отсоединить от программатора и соединить с usb-uart переходником для передачи информации на микроконтроллер от компьютера. Кварцевого резонатора в схеме нет. Практика показала что uart может работать и без него. uart - это асинхронный интерфейс т.е. передатчик передает биты через какие то определенные промежутки времени а приемник должен принимать биты через промежутки времени такие же. Иначе приемник будет принимать не то что нужно. К счастью некотарая доля синхронности в этом интерфейсе есть т.к. запускается прием только после возникновения запускающего импульса и асинхронность присутствует только в течении приема одного байта информации (если uart настроен на один байт т.е. 8 бит). Поэтому uart может работать при некотором небольшом несовпадении частот. Чем меньше скорость передачи тем больше может быть это несовпадение. Чтобы это несовпадение было почти нулевым и микроконтроллер мог работать по uartу на очень больших скоростях и очень стабильно и наверняка надежно, нужны специальные кварцевые резонаторы, например не на 1 или 2 МГц а на 1.8432 МГц для того чтобы время тактового импульса было кратным времени одного импульса по стандартам для uart. Естественно uart будет работать и при обычных кварцевых резонаторах (на Ардуине же он как то работает при кварцевых резонаторах с резонансной частотой 16 МГц). В данном случае для простоты мы не будем использовать такие редкие кварцевые резонаторы а используем внутренний rc генератор микроконтроллера с установленной по умолчанию на заводе частотой 1 МГц. Практика показала что uart при этом работает а также при такой частоте микроконтроллер может работать и при пониженном напряжении что позволяет его использовать например при питании от одной ячейки LiFePO4 аккумулятора что удобно для изготовления каких нибудь маленьких радиоуправляемых игрушек или роботов. Рассмотрим ассемблерный код программы:



Первые 4 команды а также инициализация стека, настройка пина на выход были рассмотрены в предыдущих уроках. Адрес ячейки памяти на которую переводиться выполнение программы после того как сработало прерывание по приему байта называется URXCaddr. После того как это прерывание возникло команда RJMP переводит выполнение программы на подпрограмму обработки прерывания. Но чтобы это смогло произойти сначала нужно настроить uart микроконтроллера для этого (а точнее для нашей текущей задачи) есть 5 регистров. Причем в данном случае 2 из них можно даже не трогать. Для начала можно настроить скорость. Слишком большую выбирать нельзя чтобы uart нормально работал. Можно выбрать например 9600 - эта скорость часто используется и подходит во многих случаях. Настраивается скорость через регистры UBRRL и UBRRH. В эти регистры нужно записать число соответствующее нужной нам скорости. Если это число больше 255 то надо младшие разряды этого числа записать в регистр UBRRL а старшие в UBRRH. Если меньше то можно это число записать в UBRRL а UBRRH не трогать вообще т.к. там нули по умолчанию. Чтобы определить это число не обязательно его рассчитывать по формулам. Можно просто найти его из таблицы в документации на микроконтроллер:

Также из этой таблицы видно что в нашем случае можно получить меньшую ошибку если установить бит удвоения скорости в единицу. Находиться этот бит в регистре UCSRA там он под номером 1 (самый первый это нулевой). После того как 3 регистра настроены осталось ещё 2. Разрешить прием байта и прерывание по завершению приема можно настройкой UCSRB. Чтобы разрешить прием, в единицу устанавливается бит 4 этого регистра, чтобы разрешить прерывание по приему, в единицу устанавливается бит 7 этого регистра. Последний регистр UCSRC надо настроить так чтобы принимать по 8 бит. Обычно так всегда и делается но в некоторых случая можно сделать по другому. Чтобы настроить прием 8ми бит нужно в записать единицы в бит 1 и бит 2 регистра UCSRC. Хотя этого можно было бы и не делать т.к. там по умолчанию и так имеются единицы:

Но зато теперь если вдруг понадобиться изменить количество принимаемых бит известно как это сделать. Далее в программе настраивается пин к которому подключен светодиод и разрешаются все прерывания. В основном цикле опять ничего интересного (хотя можно его заполнить например динамической индикацией или ещё чем нибудь). Когда бит приходит по uartу и возникает прерывание нужно вытащить из регистра UDR этот бит и поместить в какой либо регистр общего назначения например R18. Далее командой сравнения CPI и командой условного перехода если не равно BRNE сделать ветвление и организовать зажигание светодиода когда пришел ASCII код символа "a" и гашение светодиода когда пришел ASCII код символа "b". ASCII коды всех символов можно узнать из таблицы ASCII кодов всех символов:

Команда RETI делает выход из подпрограммы обработки прерывания. О том как откомпилировать программы и загрузить её в микроконтроллер можно узнать из предыдущих уроков. Если компиляция и загрузка прошли успешно то можно подключить микроконтроллер к компьютеру через usb-uart переходник и попробовать зажечь светодиод. Отправить какой либо символ с компьютера через переходник можно используя например Arduino IDE или же это можно сделать через командную строку. Если на компьютере обычная ОС Winows напр. 7 то например командой 

mode COM3 BAUD=9600 PARITY=n DATA=8

Можно настроить этот переходник на нужную скорость и количество бит. Вместо COM3 нужно вписать название своего com порта который появляется после втыкания переходника в usb разъем. Отправить символ а можно командой

echo a > COM3

символ b соответственно командой

echo b > COM3

Вместо COM3 нужно вписать название своего com порта который появляется после втыкания переходника в usb разъем. После написания команды надо нажимать Enter чтобы символ отправился. В моем случае всё сработало, можно убедиться в этом посмотрев видео:


Комментариев нет:

Отправить комментарий