Изучение последовательного порта UART
Методическое указание к лабораторной работе на учебном стенде LESO1.
1 Цель работы
- Изучить схему подключения микроконтроллера к компьютеру.
- Изучить особенности работы последовательного асинхронного порта UART.
- Освоить методику расчета скорости последовательного порта.
- Изучить особенности программирования UART.
- Изучить способы отладки программ на учебном лабораторном стенде LESO1.
2 Предварительная подготовка к работе
- По конспекту лекций и рекомендуемой литературе изучить принцип работы последовательного асинхронного порта UART.
- По документации изучить особенности порта UART микроконтроллера ADuC842.
- Составить алгоритм работы программы, соответственно заданию.
- Составить программу на языке программирования С.
3 Краткие теоретические сведения
3.1 Последовательный асинхронный интерфейс UART
Последовательный интерфейс использует одну сигнальную линию для передачи данных, по которой биты информации передаются друг за другом последовательно. При последовательной передаче сокращается количество сигнальных линий, что упрощает разводку проводников на печатной плате, уменьшает габариты устройства и позволяет делать более помехозащищенные интерфейсы. При последовательной передаче каждый информационный бит должен сопровождаться импульсом синхронизации — стробом. Если импульсы синхронизации передаются от одного устройства к другому по выделенной линии, то такой интерфейс называют синхронным, в этом случае генератор синхронизации располагается на стороне устройства инициирующего передачу. Если же приемник и передатчик содержат каждый свой генератор синхроимпульсов, работающий на одной частоте, то такой интерфейс называется асинхронным. Получается, что приемник информации сам вырабатывает синхроимпульсы.
Типичный представитель асинхронного последовательного интерфейса — UART (Universal Asynchronous Receiver-Transmitter — универсальный асинхронный приёмопередатчик).
При передаче по интерфейсу UART каждому байту данных предшествует СТАРТ-бит, сигнализирующий приемнику о начале посылки, за СТАРТ-битом следуют биты данных. Завершает посылку СТОП-бит, гарантирующий паузу между посылками. СТАРТ-бит следующего байта посылается в любой момент после СТОП-бита, то есть между передачами возможны паузы произвольной длительности. СТАРТ-бит, обеспечивает простой механизм синхронизации приемника по сигналу от передатчика. Внутренний генератор синхроимпульсов приемника использует счетчик-делитель опорной частоты, обнуляемый в момент приема начала СТАРТ-бита. Этот счетчик генерирует внутренние стробы, по которым приемник фиксирует последующие принимаемые биты.
3.2 Особенности работы UART микроконтроллера ADuC842
В микроконтроллере ADuC842 последовательный порт UART является полнодуплексным — позволяет передавать и принимать данные одновременно. В рассматриваемом микроконтроллере прием через последовательный порт буферизирован: порт может начать принимать байт данных еще до того как предыдущий байт будет считан из буферного регистра приемника. Однако, если до конца приема предыдущий байт не будет считан из буфера, он будет потерян: новый принятый байт перезапишет старый.
Принимаются и передаются данные по разным линиям, передача происходит через вывод TxD микроконтроллера (Transmitter Data — передатчик данных), прием — через RxD (Receiver Data — приемник данных). Физически выводы RxD и TxD совмещены с выводами третьего параллельного порта P3.0 и P3.1 соответственно.
Программное взаимодействие с последовательным портом UART осуществляется через регистры специальных функций (SFR) SBUF и SCON. Через SBUF (Serial buffer — последовательный буфер) осуществляется доступ к регистрам приемника и передатчика последовательного порта. Когда программно производится запись в SBUF, то данные загружаются в регистр передатчика, когда же программой происходит чтение SBUF, то осуществляется доступ к регистру приемника. Физически регистры приемника и передатчика разделены. SFR адрес — 0х99.
SCON — регистр конфигурации и управления последовательным портом микроконтроллера.
SFR адрес — 0x98.
Значение после подачи питания 0x00.
Регистр имеет побитовую адресацию.
Таблица 1 – Назначение бит регистра SCON
номер | мнемоника | описание | |||||||||||||||
7 | SM0 | SM1, SM0 биты определяют режим работы последовательного порта.
|
|||||||||||||||
6 | SM1 | ||||||||||||||||
5 | SM2 | Бит управления режимом приемопередатчика. Устанавливается программно для запрета приема сообщения, в котором девятый бит имеет значение “0”. Такой режим используется при реализации сетевого протокола в многопроцессорной системе. | |||||||||||||||
4 | REN | Бит разрешения приема данных через последовательный порт. Устанавливается программно, для разрешения приема. | |||||||||||||||
3 | TB8 | 9-ый бит передатчика последовательного порта. Данные загруженные в TB8 передаются девятым битом. Это актуально для режима работы UART 2 и 3. | |||||||||||||||
2 | RB8 | 9-ый бит приемника последовательного порта. В режиме работы 2 и 3 в этот бит загружается принятый девятый бит данных. В режиме 1 в этом бите хранится СТОП-бит. | |||||||||||||||
1 | TI | Флаг прерывания передатчика последовательного порта. Устанавливается аппаратно при окончании передачи байта. Флаг должен сбрасываться (запись “0”) программно. | |||||||||||||||
0 | RI | Флаг прерывания приемника последовательного порта. Устанавливается аппаратно при окончании приема байта. Флаг должен сбрасываться (запись “0”) программно. |
Режим работы 0: режим 8-битного сдвигового регистра. Для выбора этого режима работы следует в биты SM0 и SM1 записать логические нули (SM1 = 1 и SM0 = 0). В этом режиме данные последовательно передаются и принимаются через вывод RxD. Вывод TxD используется для подачи тактовых импульсов. Передача инициируется любой инструкцией, записывающей данные в регистр SBUF. Передача байта данных начинается с младшего значащего бита. Прием начинается, когда бит разрешения приема установлен в единицу (REN = 1), а флаг прерывания приемника сброшен в ноль (RI = 0). Таким образом, в данном случае последовательный порт работает в синхронном режиме, поэтому у некоторых семейств микроконтроллеров такой последовательный порт называется не UART, а USART (Universal Synchronous-Asynchronous Receiver-Transmitter — универсальный синхронный - асинхронный приемопередатчик).
Режим работы 1: асинхронный 8-битный режим с настраиваемой скоростью. Для выбора первого режима следует в бит SM0 записать единицу, а в бит SM1 — ноль (SM1 = 0 и SM0 = 1). Вывод микросхемы TxD используется для передачи информации, вывод RxD — для приема.
Передача байта информации начинается с посылки СТАРТ-бита, за ним идут восемь информационных бит, заканчивается передача СТОП-битом. Таким образом, для передачи каждого байта информации используется 10 бит. Формирование СТАРТ-бита и СТОП-бита происходит автоматически.
Скорость передачи может устанавливаться Таймером 1 или Таймером 2, или комбинацией их обоих: один — для передачи, другой — для приема. Использование таймеров 1 и 2 характерно для всего семейства MCS-51/52, правда Таймер 2 есть только в старших моделях, но в микроконтроллере ADuC842 возможна синхронизация приемопередатчика UART от специального Таймера 3, что позволяет освободить таймеры общего назначения для выполнения других функций.
Передача данных начинается, когда в регистр SBUF программно записывается передаваемое число. Данные передаются до тех пор, пока на TxD не поступит СТОП-бит, после чего флаг прерывания передатчика (TI) установится в единицу, как это показано на рисунке ниже:
Для разрешения приема данных через последовательный порт в бит REN следует записать логическую единицу. Прием байта данных начинается с приходом на линию RxD СТАРТ-бита: перехода линии из высокого логического уровня в низкий. По окончанию приема всего байта флаг прерывания приемника RI устанавливается в единицу, и принятый байт может быть программно считан из буферного регистра SBUF.
Режим работы 2: асинхронный 9-битный режим с фиксированной скоростью. Скорость передачи данных по умолчанию fcore/32, но если записать в бит SMOD регистра PCON логическую единицу, то скорость передачи будет удвоена: fcore/16. Для выбора второго режима следует в бит SM0 записать логический ноль, а в бит SM1 — единицу (SM1 = 1 и SM0 = 0).
В этом режиме каждая передаваемая или принимаемая посылка состоит из одиннадцати бит: СТАРТ-бит, восемь информационных бит, девятый программируемый бит и СТОП-бит. Девятый бит часто используют в качестве бита паритета при контроле четности, хотя он может быть использован для любых других целей.
Прием и передача во втором режиме осуществляется аналогично первому режиму. Девятый бит при передаче программно записывается в бит TB8 регистра SCON, при приеме девятый бит находится в RB8 регистра SCON.
Режим работы 3: асинхронный 9-битный режим с настраиваемой скоростью. Для выбора третьего режима следует в биты SM0 и SM1 записать логические единицы (SM1 = 1 и SM0 = 1). В этом режиме последовательный порт UART работает также как в режиме 2, только скорость задается таймерами 1, 2 или 3, так же, как и в режиме 1.
Во всех четырех режимах передача данных начинается любой инструкцией, записывающей в регистр SBUF число. В режиме 0 прием начинается при условии RI = 0 и REN = 1. Во всех остальных режимах прием начинается с приходом СТАРТ-бита при условии, что в бит REN записана логическая единица (REN = 1).
3.3 Расчет параметров синхронизации UART
По умолчанию последовательный порт микроконтроллера ADuC842 настроен на синхронизацию от Таймера 1. Скорость передачи UART определяется временем переполнения таймера:
где TT – время срабатывания таймера.
Таймер должен быть сконфигурирован для работы в режиме с автоперезагрузкой (режим 2). Для установки такого режима в старшие 4 бита регистра TMOD следует записать бинарную комбинацию 0010b. В этом случае скорость передачи данных будет определяться по формуле:
где: fcore – частота ядра микропроцессора, TH1 – содержимое регистра данных TH1.
Из формулы 2 легко найти значение регистра TH1, обеспечивающего требуемую скорость:
Результат вычисления должен быть округлен до ближайшего целого.
Используя Таймер 1 для синхронизации UART не всегда возможно получить требуемую частоту с достаточной точностью. Например, пусть при тактовой частоте ядра микропроцессора 2097кГц (значение для ADuC842 по умолчанию), требуется получить скорость передачи 19.2 кбит/с. По формуле 3 найдем значение TH1:
Используя полученное значение TH1, рассчитаем реальную скорость передачи UART:
Реальная скорость на 14% меньше требуемой, а это значит, что передача данных невозможна. Проблема была решена добавлением специального таймера 3, специализированного для высокоточной синхронизации UART в широком диапазоне частот. Кроме того, использование специализированного таймера высвобождает таймеры общего назначения для решения других различных задач.
Таймер 3, по сути, представляет собой набор настраиваемых делителей тактовой частоты ядра, структурная схема таймера изображена на рисунке ниже:
Для управления Таймером 3 предназначены два регистра специальных функций — T3CON и T3FD. Регистр T3CON содержит бит T3EN, при записи в него логической единицы синхронизация UART будет происходить от Таймера 3, в противном случае — от Таймера 1. Младшие три бита регистра T3CON определяют двоичный делитель DIV. Дробный коэффициент деления настраивается регистром T3FD.
T3CON – регистр конфигурации Таймером 3.
SFR адрес — 0x9E.
Значение после подачи питания 0x00.
Регистр не имеет побитовой адресации.
Таблица 2 – Назначение битов регистра T3CON
номер | мнемоника | описание | ||||||||||||||||||||||||||||||||||||
7 | T3EN | Разрешение Таймера 3. Когда бит установлен (T3EN = 1) синхронизация приемника и передатчика последовательного порта происходит от Таймера 3. Когда бит сброшен (T3EN = 0) — синхронизация от Таймера 1. |
||||||||||||||||||||||||||||||||||||
6 | Не используются | |||||||||||||||||||||||||||||||||||||
5 | ||||||||||||||||||||||||||||||||||||||
4 | ||||||||||||||||||||||||||||||||||||||
3 | ||||||||||||||||||||||||||||||||||||||
2 | DIV2 | Биты целочисленного делителя DIV.
|
||||||||||||||||||||||||||||||||||||
1 | DIV1 | |||||||||||||||||||||||||||||||||||||
0 | DIV0 |
T3FD – регистр Таймера 3.
SFR адрес — 0x9D.
Значение после подачи питания 0x00.
Регистр не имеет побитовой адресации.
Используя структурную схему Таймера 3 легко записать аналитическое выражение для расчета результирующей скорости последовательного порта:
где fcore — частота ядра микроконтроллера.
Значение делителя DIV можно определить по формуле 5, полученное значение следует округлить до целого вниз.
Дробный делитель T3FD можно найти по формуле 6, полученное значение следует округлить до ближайшего целого.
Рассчитаем параметры конфигурации Таймера 3, для предыдущего примера: при тактовой частоте ядра микропроцессора 2097кГц, требуется получить скорость передачи 19.2 кбит/с.
Таким образом, ошибка установления скорости составляет всего 0.2%.
3.4 Особенности представления текстовой информации
В различных операционных системах для представления текстовой информации используют специальные наборы символов. Как правило, такой набор представляют в виде таблице, где каждому символу соответствует бинарная последовательность длиною в один или несколько байт. В литературе подобную таблицу символов часто называют «кодировкой». На сегодняшний день наиболее распространенным является код ASCII (American Standard Code for Information Interchange — американский стандартный код для обмена информацией), который используется для внутреннего представления символьной информации в операционной системе MS DOS, в Блокноте операционной системы Windows, а также для кодирования текстовых файлов в Интернет.
Поскольку первоначально ASCII предназначался для обмена информации, в нём, кроме информационных символов, используются символы-команды для управления связью. В приведенной таблице такие символы показаны многоточием.
Таблица 3 – Таблица ASCII
.0 | .1 | .2 | .3 | .4 | .5 | .6 | .7 | .8 | .9 | .A | .B | .C | .D | .E | .F | |
0. | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
1. | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2. | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | — | . | / | |
3. | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
4. | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
5. | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
6. | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
7. | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | ... |
Таблица кодов содержит 8 столбцов и 16 строк, каждая строка и столбец пронумерованы в шестнадцатеричной системе счисления. Шестнадцатеричное представление ASCII-кода складывается из номера столбца и номера строки, в которых располагается символ, при этом номер строки образуют первую цифру (старшие четыре бита), а номер столбца вторую цифру (младшие 4 бита). Так, например, ASCII-код символа “E” есть число 0x45, а символа “\“ — 0x5C.
Легко заметить, что в приведенной таблице представлено 128 символов, притом, что один символ кодируется байтом — восьмью битами. Дело в том, что верхние значения (128—255) могут занимать различные дополнительные символы, например, набор русского алфавита, это зависит от конкретного типа кодировки.
3.5 Способы программной реализации работы UART
Перед первым обращением к приемо-передатчику UART последовательный порт должен быть настроен: определен режим работы, выбран и настроен источник синхронизации. Режим работы UART устанавливается битами SM0 и SM1 регистра SCON. Так как регистр имеет как байтовую, так и битовую адресацию, выполнить настройку можно разными способами: записать в регистр SCON требуемое число или установить каждый бит отдельно. Источник синхронизации определяется битом T3EN регистра T3CON: если в этот бит записать логическую единицу, то синхронизация будет происходить от Таймера 3, если ничего не записывать (по умолчанию T3EN = 0), то синхронизация от Таймера 1.
При использовании Таймера 1 необходимо сконфигурировать его для работы в режиме 2 (свободнобегущий таймер с автоперезагрузкой), для этого в старшие четыре бита регистра SMOD следует записать двоичную комбинацию 0010b. Регистр счетчика TH1 определяет скорость передачи информации по UART, его значение следует рассчитать по формуле 3. После записи TH1 таймер нужно запустить, делается это записью в бит TR1 регистра TMOD логической единицы.
При синхронизации от Таймера 3, по формулам 5 и 6 рассчитываются делители DIV и T3FD. Если запись делителя T3FD делается непосредственно в регистр T3FD, то делитель DIV определяется младшими тремя битами регистра T3CON, при этом в старший бит этого регистра (T3EN) должна быть записана логическая единица. Запуск таймера происходит автоматически.
Отправление данных по UART начинается любой командой, результат выполнения которой записывается в регистр SBUF:
SBUF =0x45; // отправить символ “E”
Можно каждый раз не пользоваться таблицей ASCII для определения кода символа, в языке «Си» для этого есть удобный инструмент: достаточно взять требуемый символ в апострофы, компилятором это будет интерпретировано как код символа.
SBUF ='E'; // отправить символ “E”
Если же требуется отправить не один символ, то прежде чем следующий код будет записан в SBUF, следует подождать, пока предыдущий символ будет отправлен. О конце передачи сигнализирует флаг TI регистра TCON, когда передача завершена, в бит TI аппаратно записывается логическая единица. Можно программно организовать в цикле проверку TI на равенство нулю, а следующий байт отправлять только тогда, когда TI окажется равен единице:
SBUF = 0x45; // отправить символ “E” while(!TI); // пока TI равен нулю, выполнять пустой цикл TI = 0; // сбросить флаг для следующей передачи
Аналогично выполняется и прием байта. Принятый байт может быть считан из буферного регистра лишь тогда, когда был принят последний бит и флаг приема RI установлен.
while(!RI); // ждем завершение приема байта cmd = SBUF; // считываем принятый байт в переменную cmd RI = 0; // сброс флага приема
В приложениях, где время выполнение критично недопустимо тратить много времени при передаче на ожидание пока байт будет отправлен и буфер освободится, в этом случае можно не дожидаясь полной отправки байта приступить к выполнению дальнейшей программы, но перед отправкой следующего байта нужно убедиться, что буфер освободился и передатчик готов к работе. Участок программы, отправляющий байт данных можно переделать следующим образом:
while(!TI); // подождать, пока буфер передачи не освободится (если занят) SBUF = 0x45; // заполнить буфер и начать передачу TI = 0; // сбросить флаг передачи в нуль
С таким вариантом реализации устраняются паузы на выполнение программы между передачами отдельных байтов.
Ниже на рисунке 3 приведены адреса регистров специальных функций, используемых в работе.
Рисунок 3 – Адреса регистров специальных функций
При написании программы следует помнить, что программа для микроконтроллера должна выполняться до отключения питания устройства и не может быть завершена. Поэтому программа должна содержать бесконечный цикл.
3.6 Взаимодействие микроконтроллера с персональным компьютером
Учебный лабораторный стенд LESO1 подключается к персональному компьютеру через микросхему преобразователя интерфейсов USB-UART. Для связи с микроконтроллером в программе загрузчика nwFlash реализован терминал. Терминал позволяет посылать через последовательный порт в микроконтроллер информацию, принимать и отображать принятую из микроконтроллера информацию. Настройка терминала осуществляется в пункте главного меню «Опции терминала». Опции терминала позволяют:
- выбрать режим отображения данных: текстовый или шестнадцатеричный, при этом изменяется также тип посылаемых данных;
- выбрать кодировку ANSI (Windows-1251) или ASCII (DOS-866);
- включать и выключать режим автоматической прокрутки текста;
- очистить окно терминала;
- сохранять принятую от микроконтроллера информацию в файл:
- в том виде, как она пришла — пункт меню «Сохранить»;
- в том виде, как она отображается в терминале — пункт меню «Сохранить как текст».
На рисунке 4 показана вкладка главного меню «Опции терминала».
При обмене данными с учебным стендом необходимо установить требуемую скорость подключения. Сделать это можно в меню «подключение», как это показано на рисунке 5.
4 Задание к работе в лаборатории
4.1 Вывод информации через последовательный порт
- Разработайте алгоритм программы, передающей через последовательный порт UART данные в персональный компьютер — фамилию студента. Скорость передачи данных должна соответствовать варианту (таблица 5). Источник синхронизации UART (Таймер 1 или Таймер 3) согласовывается с преподавателем. Взаимодействие микроконтроллера с компьютером осуществляется через терминал программы загрузчика — nwFlash.
- По таблице регистров специальных функций (SFR) определите адреса регистров управления и настройки последовательного порта.
- Определите значение регистров настройки последовательного порта и таймера, используемого для синхронизации.
- Рассчитайте значения регистров таймера, используемого для синхронизации.
- Войдите в интегрированную среду программирования Keil-C. Создайте и настройте должным образом проект.
- Разработайте и введите текст программы в соответствии с созданным алгоритмом.
- Оттранслируйте программу, и исправьте синтаксические ошибки.
- Настройте скорость UART терминала программы nwFlash соответственно заданию.
- Загрузите полученный *.hex файл в лабораторный стенд LESO1.
- Убедитесь, что в окне терминала вывелась фамилия студента.
4.2 Управление микроконтроллером через последовательный порт (дополнительно)
- Измените программу таким образом, чтобы данные из микроконтроллера отсылались только по команде, переданной с компьютера. Передача команды осуществляется через терминал nwFlash.
- Загрузите полученный *.hex файл в лабораторный стенд LESO1.
- Убедитесь, что программа работает должным образом.
Таблица 5 – Варианты заданий
номер вариант | скорость UART |
1 | 300 бит/с |
2 | 600 бит/с |
3 | 1200 бит/с |
4 | 1800 бит/с |
5 | 2400 бит/с |
6 | 4800 бит/с |
7 | 7200 бит/с |
8 | 9600 бит/с |
9 | 600 бит/с |
10 | 1200 бит/с |
11 | 1800 бит/с |
12 | 2400 бит/с |
13 | 4800 бит/с |
14 | 7200 бит/с |
15 | 9600 бит/с |
5 Указания к составлению отчета
Отчет должен содержать:
- Цель работы.
- Диаграмму передачи данных по последовательному порту.
- Расчет параметров синхронизации (настройки таймеров).
- Графическую схему алгоритма работы программы.
- Исходный текст программы.
- Содержимое файла листинга программного проекта.
- Выводы по выполненной лабораторной работе.
Схемы, а также отчет в целом, выполняются согласно нормам ЕСКД.
Комментарии:
чт, 10/19/2017 - 18:42
Постоянная ссылка (Permalink)
Добрый день. А как можно реализовать вывод информации, при вводе символа? вначале до мейна инициализирую char='z';
потом настраиваю синхронизацию и порт и затем вставляю это
а ниже вывод буквы. Просто буква выводится, а с вводдом команды z нет. как решить проблему?
чт, 10/19/2017 - 21:35
Постоянная ссылка (Permalink)
Я верно понял, вам нужно выводить информацию только по приему команды?
Я бы сделал так. В бесконечном цикле ждал приема байта, если байт принят, то проверял бы на равенство заданному символу ( у вас в задании это 'z', да?) и если принятый символ равен требуемому, то запускал бы передачу данных. Приведите весь код, посмотрим что не так.
вт, 10/31/2017 - 19:52
Постоянная ссылка (Permalink)
Вот такой вот код. Без ввода команды выводит, а если добавляю команды для ввода z, обратно не возвращает ничего.
вт, 10/31/2017 - 20:19
Постоянная ссылка (Permalink)
Разберем код:
Ваша программа должна работать так: после сброса контроллера он выводит в терминал символ z и ждет прихода любого символа. После того, как любой символ будет получен, он выводит "Syganovz" и опять ждет символа. Я не думаю, что это то, что требуется. Для приема символа в начале цикла
while
ставим такой блок:Затем проверяем этот символ на равенство 'z':
чт, 11/02/2017 - 11:38
Постоянная ссылка (Permalink)
Я бы порекомендовал передачу символа оформить в виде отдельной функции. Классическое название для нее
putchar
Тогда отправка фамилии будет выглядеть проще: