Как уже упоминалось, у ATmega2560 имеется 4 последовательных порта USART: USART0, USART1, USART2 и USART3, которые фиксировано привязаны к определенным ножкам корпуса микроконтроллера. Т. е. определенный вывод микроконтроллера может работать либо просто как порт ввода/вывода, либо как аппаратный вход или выход интерфейса USART. Все зависит от программной настройки - данных, которые Вы запишете в управляющие регистры микроконтроллера. В таблице и на картинке показана привязка аппаратуры USART к выводам микроконтроллера.
Имя |
Прерывания |
Регистры |
Порты RXD, TXD, XCK |
USART0 |
UDRE0, TXC0, RXC0 |
UDR0, UCSR0A, UCSR0B, UCSR0C, UBRR0L, UBRR0H |
PE0, PE1, PE2 |
USART1 |
UDRE1, TXC1, RXC1 |
UDR1, UCSR1A, UCSR1B, UCSR1C, UBRR1L, UBRR1H |
PD2, PD3, PD5 |
USART2 |
UDRE2, TXC2, RXC2 |
UDR2, UCSR2A, UCSR2B, UCSR2C, UBRR2L, UBRR2H |
PH0, PH1, PH2 |
USART3 |
UDRE3, TXC3, RXC3 |
UDR3, UCSR3A, UCSR3B, UCSR3C, UBRR3L, UBRR3H |
PJ0, PJ1, PJ2 |
Порты USART обладают следующими основными возможностями:
• Поддерживают полный дуплекс (имеют независимые аппаратные буферы приема и передачи).
• Могут работать асинхронно и синхронно.
• В синхронном режиме могут либо вырабатывать такты, либо использовать внешнее тактирование (Master or Slave Clocked Synchronous Operation).
• Генератор скорости передачи, настраиваемый с высокой точностью (High Resolution Baud Rate Generator).
• Поддерживает размеры фрейма передачи из 5, 6, 7, 8 или 9 бит данных и 1 или 2 стоповых бита.
• Аппаратная поддержка генерации и проверки на нечетность или четность (Odd or Even Parity).
• Детектирование потери данных на приеме (Data OverRun Detection).
• Детектирование ошибок фрейма (Framing Error Detection).
• Фильтрация помех (Noise Filtering) с помощью цифрового ФНЧ, включающая детектирования ошибочного стартового бита.
• 3 отдельных прерывания по событиям TX Complete, TX Data Register Empty и RX Complete.
• Режим обмена с несколькими процессорами (Multi-processor Communication Mode).
• Асинхронный режим с двойной скоростью (Double Speed Asynchronous Communication Mode).
Для уменьшения общего энергопотребления кристалла ненужные USARTn могут быть полностью выключены с помощью битов управления регистров PRR0 и PRR1.
Порт USART0 используется в платах Arduino Mega 2560 [2] под аппаратный мост USB-UART, чтобы обеспечить работу загрузчика кода и поддержку отладочного вывода через Serial Monitor.
Рис. 22-1. Блок-диаграмма внутреннего устройства USART.
На диаграмме пунктирными линиями выделены 3 отдельных блока USART (перечисленные далее сверху вниз): Clock Generator (тактовый генератор), Transmitter (передатчик) и Receiver (приемник). Регистры управления общие для всех этих блоков. Логика Clock Generation состоит из логики синхронизации для внешних тактов (SYNC LOGIC, используется в подчиненном режиме для синхронизации передачи бит), и генератора скорости передачи (BAUD RATE GENERATOR). Вывод XCKn (такты передачи) используется только для синхронного режима работы (synchronous transfer mode). Передатчик состоит из одиночного буфера записи (UDR), последовательного регистра сдвига (TRANSMIT SHIFT REGISTER), генератора четности (PARITY GENERATOR) и логики управления (TX CONTROL) для поддержки разных форматов фрейма. Наличие аппаратного буфера фрейма позволяет вести непрерывные передачи без задержек между отдельными фреймами. Приемник наиболее сложный узел USART, потому что он имеет узлы восстановления тактов (CLOCK RECOVERY) и данных (DATA RECOVERY), которые используются для асинхронного приема данных. В дополнение к узлам восстановления приемник содержит блок проверки на четность (PARITY CHECKER), логику управления (RX CONTROL), регистр сдвига и двухуровневый буфер приема (UDR). Приемник поддерживает одинаковый формат фрейма, который использует передатчик, и может детектировать ошибку фрейма (Frame Error), событие потери данных на приеме (Data OverRun) и ошибку четности (Parity Error). Модуль PIN CONTROL управляет поведением порта микроконтроллера - или этот вывод работает как обычный порт ввода/вывода GPIO, или он подключен к аппаратуре USART и выполняет специальную функцию.
[Генерация тактов]
Логика генерации тактов синтезирует базовую частоту синхронизации для передатчика и приемника. The USARTn поддерживает 4 режима тактирования: нормальный асинхронный (Normal asynchronous), асинхронный двойной скорости (Double Speed asynchronous), синхронный главный (Master synchronous) и синхронный подчиненный (Slave synchronous). Бит UMSELn в USART Control and Status Register C (UCSRnC) выбирает между асинхронным и синхронным режимами. Двойная скорость (применимо только к асинхронному режиму) управляется битом U2Xn, находящемся в регистре UCSRnA. Когда используется синхронный режим (UMSELn = 1), регистр направления данных (Data Direction Register, DDR) для вывода XCKn определяет, каким будет тактирование для синхронного режима: внутренним (Master mode) или внешним (Slave mode). Вывод XCKn активен только в при использовании синхронного режима, в асинхронном режиме он работает как простой порт GPIO.
Рис. 22-2. Блок-диаграмма логики генерации тактов USART.
Описание сигналов:
txclk такты передатчика (внутренний сигнал).
rxclk базовые такты передатчика (внутренний сигнал).
xcki ввод от вывода XCK (внутренний сигнал). Используется для работы в синхронном подчиненном режиме (synchronous slave operation).
xcko выходной сигнал тактов для подачи на вывод XCK (внутренний сигнал). Используется для работы в синхронном подчиненном режиме (synchronous master operation).
fOSC частота вывода XTAL (System Clock, системная частота).
DDR_XCK разряд регистра DDRX, управляющий направлением работы ножки порта (вход или выход).
Baud Rate Generator, внутренняя генерация тактов. Генерация тактов внутри чипа используется для асинхронного и синхронного режимов работы. USART Baud Rate Register (UBRRn) и считающий вниз счетчик (Prescaling Down-Counter) подключены к программируемому прескалеру, или другими словами к генератору скорости передачи (Baud Rate Generator). Обратно-считающий счетчик (down-counter), работающей на системной частоте (fOSC), каждый раз загружается значением из UBRRn, когда счетчик достигает нуля, или когда записан регистр UBRRLn. В этот момент генерируется тактовый импульс для USART, появляющийся на выходе Baud Rate Generator (= fOSC/(UBRRn+1)). Передатчик делит выходную тактовую частоты Baud Rate Generator на 2, 8 или 16 в зависимости от режима. Выход Baud Rate Generator напрямую используется для тактирования приемника и узлов восстановления данных. Однако узлы восстановления используют машину состояний из 2, 8 или 16 состояний в зависимости от режима, установленного битами UMSELn, U2Xn и DDR_XCKn.
Таблица 22-1 содержит выражения для вычисления скорости baud rate (в битах на секунду) и для вычисления значения UBRRn для каждого режима работы, когда используется генерируемый внутри источник тактов.
Табл. 22-1. Формулы для расчета скорости и настроек в зависимости от режима.
Режим |
Скорость(1) |
UBRR |
Асинхронный нормальный (U2XN = 0) |
fOSC BAUD = ----------------------- 16 * (UBRRn+1) |
fOSC UBRRn = ---------------- - 1 16 * BAUD |
Асинхронный двойной скорости (U2XN = 1) |
fOSC BAUD = ----------------------- 8 * (UBRRn+1) |
fOSC UBRRn = --------------- - 1 8 * BAUD |
Синхронный главный |
fOSC BAUD = ----------------------- 2 * (UBRRn+1) |
fOSC UBRRn = --------------- - 1 2 * BAUD |
Примечание (1). Скорость передачи определена как скорость следования бит в секунду (baud rate, bit per second, bps).
BAUD Baud rate (в битах/сек, bps).
fOSC системная тактовая частота (System Oscillator clock frequency).
UBRRn содержимое регистров UBRRHn и UBRRLn (0-4095).
Некоторые примеры значений UBRRn для разных тактовых частот микроконтроллера можно найти в таблице 22-9.
Double Speed Operation (U2Xn). Скорость передачи может быть удвоена (это пошло еще от микроконтроллеров серии MCS51) путем установки бита U2Xn в регистре UCSRnA. Установка этого бита дает эффект только для асинхронной работы USART, сбросьте этот бит в 0 для синхронного функционирования.
Установка бита U2Xn уменьшит коэффициент деления синтезатора скорости с 16 до 8, что соответствует удвоению скорости передачи и приема для асинхронного режима. Имейте в виду, что приемник в этом случае будет делать в 2 раза меньше выборок при восстановлении данных и тактов (количество выборок также уменьшиться с 16 до 8), так что для удвоения скорости с сохранением точной установки скорости понадобится более точно выдерживать системную частоту. Это важно для приемника, а для передатчика нет никаких проблем.
Внешнее тактирование. Используются в подчиненном синхронном режиме работы. Внешние такты поступают от вывода XCKn (см. рис. 22-2), и их значения выбираются регистром синхронизации, чтобы уменьшить шансы нестабильности. Выход регистра синхронизации затем должен поступить сначала на детектор перепада, перед тем как сигнал тактов можно было использовать в передатчике и приемнике. Этот процесс занимает два цикла системной тактовой частоты CPU, так что эта задержка ограничивает максимально возможную тактовую частоту XCKn:
fOSC
fXCK < ------
4
Имейте в виду, что fOSC зависит от стабильности частоты источника системных тактов. Так что рекомендуется добавить некоторый запас, чтобы избежать возможных потерь данных из-за неточной установки системной частоты.
Синхронный режим работы. Когда используется синхронный режим (UMSELn = 1), вывод XCKn будет аппаратно использоваться либо как вход тактов (подчиненное устройство), либо как выход тактов (главное устройство). Зависимость между перепадами тактов и выборкой данных остается той же самой. Базовый принцип состоит в том, что вход данных (on RxDn) оцифровывается по противоположному перепаду XCKn, когда меняется сигнал на выходе данных (TxDn).
Рис. 22-3. Временные диаграммы XCKn синхронного режима.
Бит UCRSC регистра UCPOLn выберет, какой из перепадов XCKn будет использоваться для выборки данных, а какой для изменения выходных данных. Как видно из рис. 22-3, когда UCPOLn == 0 данные изменяются по нарастанию XCKn и выборка делается по спаду XCKn. И наоборот, если UCPOLn == 1, то данные изменяются по спаду XCKn, и их выборка делается по фронту XCKn.
Форматы фрейма. Под фреймом подразумевается элементарная, неделимая посылка из нескольких бит. Во фрейм входят последовательно передаваемый код символа определенной разрядности, биты синхронизации (биты start и stop), и опционально бит четности для проверки на ошибку. USART позволяет настроить все 30 комбинаций следующих допустимых форматов фрейма:
• 1 start-бит
• 5, 6, 7, 8 или 9 бит данных
• no, even или odd parity bit (бит четности отсутствует, есть бит четности или есть бит нечетности)
• 1 или 2 stop-бита
Фрейм начинается start-битом, за которым идет наименее значащий бит данных (least significant bit, LSB). Далее идут биты данных (всего бит данных может быть от 5 до 9), завершающий бит самый старший (most significant bit, MSB). Если контроль четности разрешен, то за битами данных, перед stop-битами вставляется бит четности. Когда весь фрейм передан, то за ним может без задержки следовать следующий фрейм, или обмен может перейти в состояние ожидания idle, когда на линии данных уровень лог. 1. На рис. 22-4 показаны возможные комбинации форматов фрейма. Биты внутри квадратных скобок опциональны.
Рис. 22-4. Форматы фрейма.
St start-бит, всегда лог. 0.
(n) биты данных (от 0 до 8).
P Parity bit, бит четности. Может быть битом нечетности, или битом четности (odd или even, в зависимости от настройки).
Sp stop-бит, всегда лог. 1.
IDLE нет активности на линии передачи (RxDn или TxDn). В состоянии IDLE на линии всегда должен быть уровень лог. 1.
Используемый формат фрейма USART устанавливается битами UCSZn2:0, UPMn1:0 и USBSn в регистрах UCSRnB и UCSRnC. Приемник и передатчик использует одну и ту же настройку. Имейте в виду, что изменение настроек этих бит во время осуществления активного обмена повредит данные передатчика и приемника.
Биты размера символа USART (UCSZn2:0) выбирают количество бит данных во фрейме. Биты режима четности USART Parity mode (UPMn1:0) разрешают и устанавливают тип контроля четности. Выбор между одним или двумя stop-битами устанавливается битом USART Stop Bit Select (USBSn). Приемник игнорирует второй stop-бит. Таким образом FE (Frame Error, ошибка фрейма) будет детектироваться в тех случаях, когда первый stop-бит равен 0.
Вычисление Parity Bit. Бит четности (parity bit) вычисляется функцией исключающее ИЛИ от всех бит данных. Если используется контроль по нечетности (odd parity), то берется результат инвертированного исключающего ИЛИ. Бит четности размещается между последним битом данных и первым (или единственным) stop-битом фрейма. Зависимость между битом четности и битами данных следующая:
Peven бит четности, когда для контроля используется четность (even).
Podd бит четности, когда для контроля используется нечетность (odd).
dn биты данных (в количестве n) передаваемого символа.
[Инициализация USART]
Чтобы можно было начать какой-либо обмен через USART, его надо инициализировать. Процесс инициализации обычно состоит из настройки скорости baud rate, установки формата фрейма и разрешения передатчика и/или приемника в зависимости от использования. Для работы с USART через систему прерываний (самый эффективный способ работы с USART) перед настройкой должен быть сброшен глобальный флаг разрешения прерываний (Global Interrupt Flag, I-флаг в регистре SREG), что означает запрет всех прерываний.
Перед тем, как делать повторную инициализацию с целью поменять baud rate или формат фрейма нужно убедиться, что сейчас активной передачи в момент изменения регистров. Для проверки, что передача завершена может использоваться флаг TXCn, и флаг RXCn может использоваться для того, чтобы узнать, есть ли не прочитанные данные в буфере приема. Имейте в виду, что флаг TXCn должен быть очищен перед каждой передачей (перед тем, как записывается регистр UDRn), если он используется с такой целью.
В следующем простом примере кода инициализации USART показан один и тот же функционал на языке ассемблера и в функции на языке C. Примеры подразумевают асинхронный режим работы с использованием опроса (без разрешенных прерываний) и фиксированного формата фрейма. Скорость (baud rate) предоставляется в виде параметра функции. Для кода на ассемблере подразумевается, что параметр baud rate сохранен в регистровую пару r17:r16.
USART_Init:
; установка baud rate
sts UBRRnH, r17
sts UBRRnL, r16
ldi r16, (1 << U2Xn)
sts UCRnA, r16
; разрешить приемник и передатчик
ldi r16, (1 << RXENn)|(1 << TXENn)
sts UCSRnB,r16
; установка формата фрейма: 8data, 1stop bit
ldi r16, (2 << UMSELn)|(3 << UCSZn0)
sts UCSRnC,r16
ret
#define FOSC 1843200 // тактовая частота системы
#define BAUD 9600
#define (MYUBRR FOSC/16/BAUD-1)
void main( void )
{
...
USART_Init ( MYUBRR );
...
}
void USART_Init( unsigned int ubrr)
{
/* Установка baud rate */
UBRRH = (unsigned char)(ubrr >> 8);
UBRRL = (unsigned char)ubrr;
/* Разрешить приемник и передатчик */
UCSRB = (1 << RXEN)|(1 << TXEN);
/* Установка формата фрейма: 8data, 2stop bit */
UCSRC = (1 << USBS)|(3 << UCSZ0);
}
Более сложные подпрограммы могут быть сделаны так, что будут учитывать формат фрейма в параметрах, делать запрет прерываний при инициализации и т. д. Однако во многих приложениях часто используется фиксированная настройка для регистров скорости и управления, и для приложений такого типа подобный код может быть напрямую вставлен в функцию main, или скомбинирован с подпрограммами инициализации для других модулей ввода/вывода.
[Передача данных – USART Transmitter]
Передатчик USART разрешается путем установки бита Transmit Enable (TXEN) в регистре UCSRnB. Когда передатчик разрешен, нормальное функционирование порта GPIO для вывода TxDn переназначается на аппаратную функцию последовательного выхода данных USART. Параметры baud rate, режим работы и формат фрейма должны быть настроены перед осуществлением любых передач. Если используется синхронный режим работы, то такты вывода XCKn принудительно будут использоваться для тактирования передачи.
Передача фреймов размером от 5 до 8 бит данных. Передача начинается с загрузки буфера передачи данными, которые должны быть переданы. CPU может загрузить данные в буфер передачи путем записи регистра UDRn по его адресу размещения в пространстве I/O. Данные, находящиеся в буфере передачи, переместятся в регистр сдвига, и будут готовы к отправке в новом фрейме. Регистр сдвига загружается новыми данными если USART находится в состоянии ожидания idle (нет активной передачи) или сразу после завершения последнего stop-бита предыдущего переданного фрейма. Когда регистр сдвига загружен новыми данными, они будут передаваться в полном фрейме со скоростью, заданной регистром Baud Register и битом U2Xn, или в зависимости от режима работы скорость будет определятся тактами на XCKn.
Следующие примеры кода показывают простую функцию передачи USART, основанную на опросе флага Data Register Empty (UDREn). Когда используются фреймы меньше 8 бит, самый старший бит, записанный в UDRn, будет игнорироваться. USART должен быть инициализирован перед тем, как можно будет использовать функцию передачи. Для кода на ассемблере подразумевается, что передаваемые данных сохранены в регистре R16.
USART_Transmit:
; Ожидание опустошения буфера передачи
lds r17, UCSRnA
sbrs r17, UDREn
rjmp USART_Transmit
; Поместить данные (r16) в буфер, отправка данных
sts UDRn,r16
ret
void USART_Transmit( unsigned char data )
{
/* Ожидание опустошения буфера передачи */
while ( !( UCSRnA & (1 << UDREn)) )
{
}
/* Поместить данные в буфер, отправка данных */
UDRn = data;
}
Функция просто ждет, пока буфер передачи не опустошится, путем постоянного опроса флага UDREn, перед тем как загрузить новые данные для передачи. Если бы было задействовано прерывание по опустошению буфера Data Register Empty, то обработчик этого прерывания записал бы данные в буфер передачи (и было бы сэкономлено время процессора, затраченное на пустые циклы ожидания опустошения буфера).
Передача фреймов размером 9 бит данных. Если используются 9-разрядные символы (UCSZn = 7), то старший девятый бит должен быть записан в бит TXB8 регистра UCSRnB перед тем, как младшие 8 бит символа должны быть записаны в регистр UDRn. Следующие примеры кода показывают функцию передачи, которая поддерживает передачу символов из 9-бит. Для кода ассемблера подразумевается, что данные для отправки сохранены в регистровой паре R17:R16.
USART_Transmit:
; Ожидание опустошения буфера передачи
sbis UCSRnA,UDREn
rjmp USART_Transmit
; Копирование 9-го бита из r17 в TXB8
cbi UCSRnB,TXB8
sbrc r17,0
sbi UCSRnB,TXB8
; Поместить LSB данные (r16) в буфер, отправка данных
sts UDRn,r16
ret
void USART_Transmit( unsigned int data )
{
/* Ожидание опустошения буфера */
while ( !( UCSRnA & (1 << UDREn))) )
{
}
/* Копирование 9-го бита в TXB8 */
UCSRnB &= ~(1 << TXB8);
if ( data & 0x0100 )
UCSRnB |= (1 << TXB8);
/* Поместить данные в буфер, отправка данных */
UDRn = data;
}
Примечание: эти функции передачи написаны только для примера. Они могут быть оптимизированы, если содержимое UCSRnB статическое. Например, после инициализации в регистре UCSRnB используется только бит TXB8.
9-й бит может использоваться для того, чтобы показать адрес фрейма в режиме обмена с несколькими процессорами (multi processor communication mode) или для другого протокола, например для синхронизации.
Флаги передатчика и прерывания. У передатчика USART есть 2 флага, которые показывают его состояние: USART Data Register Empty (UDREn) и Transmit Complete (TXCn). Оба флага можно использовать для генерации прерываний.
Флаг Data Register Empty (UDREn) показывает, готов или нет буфер передачи к записи туда новых данных. Этот бит устанавливается, когда буфер передачи опустошается, и очищается, когда буфер передачи содержит данные для отправки, которые еще пока не перемещены в регистр сдвига. Для совместимости с микроконтроллерами, которые возможно появятся в будущем, всегда записывайте этот бит в 0, когда записываете регистр UCSRnA.
Когда в бит Data Register Empty Interrupt Enable (UDRIEn) регистра UCSRnB записана 1, будет возможен запуск прерывания USART Data Register Empty, если установлен бит UDREn (подразумевается, что глобально прерывания разрешены).
UDREn очищается путем записи UDRn. Когда используется передача данных с управлением по прерываниям, подпрограмма прерывания Data Register Empty должна либо записать новые данные в UDRn, чтобы очистить UDREn, либо запретить прерывание Data Register Empty, иначе новое прерывание запустится после завершения обработчика прерывания.
Бит флага Transmit Complete (TXCn) устанавливается в 1, когда весь фрейм в регистре сдвига передачи будет выдвинут наружу, и в буфере передачи нет новых данных. Бит флага TXCn Flag автоматически очищается, когда запускается прерывание transmit complete, или этот флаг может быть очищен записью в него лог. 1. Флаг TXCn полезен при полудуплексном обмене (наподобие стандарта RS-485), где передающее приложение должно войти в режим приема и немедленно освободить шину обмена после завершения передачи.
Если бит Transmit Compete Interrupt Enable (TXCIEn) в регистре UCSRnB установлен, запустится прерывание USART Transmit Complete, когда установится флаг TXCn (подразумевается, что глобально прерывания разрешены). Когда используется прерывание transmit complete, обработчику прерывания не нужно очищать флаг TXCn, это автоматически произойдет, когда сработает прерывание.
Parity Generator. Генератор четности (Parity Generator) вычисляет бит четности для последовательного фрейма данных. Когда разрешен бит четности (UPMn1 = 1), логика управления передатчиком вставляет бит четности между последним битом данных и первым stop-битом отправляемого фрейма.
Запрет передатчика. Запрет передатчика (сброс TXEN в 0) не вступит в силу, пока происходит активная передача, т. е. пока регистр сдвига и регистр буфера передачи еще содержат данные для передачи. После того, как передатчик запрещен, но больше не будет переназначать вывод порта TxDn.
[Прием данных – USART Receiver]
Приемник USART разрешатся путем записи бита Receive Enable (RXENn) регистра UCSRnB в 1. Когда приемник разрешен, нормальная работа порта RxDn переназначается аппаратурой USART, и этот порт становится входом приемника для последовательных данных. Параметры baud rate, режима работы и формат фрейма должны быть установлены до того, как можно будет осуществлять любой прием. Если используется синхронный режим, то вывод XCKn будет использоваться как такты приема.
Прием фреймов длиной от 5 до 8 бит данных. Приемник начнет прием данных, когда детектирует допустимый start-бит. Каждый бит, который следует за стартовым, будет оцифровывается на скорости baud rate, или с тактами XCKn, и вдвигаться регистр сдвига, пока не будет принят первый stop-бит фрейма. Второй stop-бит будет приемником игнорироваться. Когда будет принят первый stop-бит, т. е. когда полный фрейм присутствует в регистре сдвига, то содержимое регистра сдвига будет перемещено в буфер приема. Буфер приема может быть прочитан через UDRn.
Следующий пример кода показывает простую функцию приема USART на базе опроса флага Receive Complete (RXCn). Когда используются фреймы размером меньше 8 бит, самый старший бит байта данных, прочитанного из UDRn, будет маскирован нулем. USART должен быть инициализирован перед использованием этой функции.
USART_Receive:
; Ожидание поступления данных
lds r17, UCSRnA
sbrs r17, RXCn
rjmp USART_Receive
; Получить и возвратить данные из буфера
lds r16, UDRn
ret
unsigned char USART_Receive( void )
{
/* Ожидание поступления данных */
while ( !(UCSRnA & (1 << RXCn)) )
{
}
/* Получить и возвратить данные из буфера */
return UDRn;
}
Функция просто ждет появления данных в буфере приема путем проверки флага RXCn перед чтением буфера и возврата значения. Это означает, что она полностью блокирует программу, если на вход USART не поступают данные.
Прием фреймов длиной 9 бит данных. Если используются 9-битные символы (UCSZn=7), то 9-й бит должен быть прочитан из бита RXB8n регистра UCSRnB до чтения младших 8 бит из UDRn. То же самое правило действует и для флагов состояния FEn, DORn и UPEn. Сначала прочитайте состояние из UCSRnA, затем данные из UDRn. Чтение UDRn по его адресу I/O поменяет состояние приемного буфера FIFO и следовательно поменяется состояние битов TXB8n, FEn, DORn и UPEn, которые все сохраняются в FIFO.
Следующий пример кода покажет простую функцию приема USART, которая обрабатывает как 9-й бит, так и биты статуса.
USART_Receive:
; Ожидание поступления данных
lds r17, UCSRnA
sbrs r17, RXCn
rjmp USART_Receive
; Получить состояние и 9-й бит, и затем данные из буфера
lds r18, UCSRnA
lds r17, UCSRnB
lds r16, UDRn
; Если ошибка, вернуть -1
andi r18,(1 << FEn)|(1 << DORn)|(1 << UPEn)
breq USART_ReceiveNoError
ldi r17, HIGH(-1)
ldi r16, LOW(-1)USART_ReceiveNoError:
; фильтр 9-го бита, вернуть символ
lsr r17
andi r17, 0x01
ret
unsigned int USART_Receive( void )
{
unsigned char status, resh, resl;
/* Ожидание поступления данных */
while ( !(UCSRnA & (1 << RXCn)) )
{
}
/* Получить состояние и 9-й бит, затем данные из буфера */
status = UCSRnA;
resh = UCSRnB;
resl = UDRn;
/* Если ошибка, вернуть -1 */
if ( status & (1 << FEn)|(1 << DORn)|(1 << UPEn) )
return -1;
/* Фильтр 9-го бита, и возврат символа */
resh = (resh >> 1) & 0x01;
return ((resh << 8) | resl);
}
Пример функции приема читает все регистры I/O в регистровый файл перед тем, как вычисления завершаться. Это дает оптимальное использование буфера, поскольку чтение ячеек буфера нужно выполнить как можно быстрее, чтобы освободить их с целью получения новых данных.
Флаг и прерывание Receive Compete. У приемника USART есть 1 флаг, который показывает состояние приемника. Флаг Receive Complete (RXCn) показывает, что в буфере приема есть не прочитанные данные. Этот флаг равен 1, когда не прочитанные данные есть в буфере приема, и 0, когда буфер приема пуст (т. е. в нем не содержится никаких не прочитанных данных). Если приемник запрещен (RXENn = 0), буфер приема сбрасывается, и следовательно флаг RXCn обнуляется.
Когда установлен бит Receive Complete Interrupt Enable (RXCIEn) в регистре UCSRnB, выполнится прерывание USART Receive Complete, когда флаг RXCn установится (подразумевается, что глобально прерывания разрешены). Когда работает прием данных по прерываниям, то подпрограмма обработчика прерывания Receive Complete должна прочитать принятые данные UDRn, чтобы очистить флаг RXCn, иначе после завершения работы обработчика прерывания снова запуститься тот же обработчик прерывания.
Флаги ошибок приемника. У приемника USART есть 3 флага ошибки: Frame Error (FEn), Data OverRun (DORn) и Parity Error (UPEn). Все биты ошибок доступны через чтение UCSRnA. Общим для флагов ошибок является то, тчо они размещены в буфере приема вместе с данными фрейма, для которого флаги ошибок показывают состояние (т. е. буферизация данных фрейма привязана к буферизации флагов ошибки). По этой причине сначала нужно прочитать UCSRnA, и только потом буфер данных приема (UDRn), поскольку чтение UDRn по его месту размещения I/O освободит буфер под новые данные. Еще флаги ошибок объединяет то, что их нельзя сбросить программно записью. Однако для обеспечения совместимости с изменениями в USART, которые возможно появятся в будущем, все флаги должны быть сброшены в 0, когда осуществляется запись UCSRnA. Флаги ошибки не могут генерировать прерывание.
Флаг Frame Error (FEn) показывает состояние первого stop-бита принятого фрейма, находящегося в буфере приема. Флаг FEn равен 0, если stop-бит был прочитан правильно (как 1), и флаг FEn будет в 1, когда stop-бит ошибочен (равен 0). Этот флаг может использоваться для детектирования событий выхода из синхронизации, событий остановки потока (break conditions) и поддержки обработки протокола. На флаг FEn не влияет настройка бита USBSn в регистре UCSRnC, поскольку приемник игнорирует все stop-биты, кроме первого. Для обеспечения совместимости с микроконтроллерами, который возможно появятся в будущем, всегда сбрасывайте этот бит в 0, когда записываете UCSRnA.
Флаг Data OverRun (DORn) показывает потерю данных, из-за того, что у буфере приемника были не прочитанные данные. Data OverRun произойдет, когда буфер приема заполнен (в нем находится 2 символа), ожидается прием следующего символа, и детектирован новый start-бит. Если флаг DORn установлен, то была потеря одного или большего количества фреймов между последним чтением и следующим чтением фрейма из UDRn. Для обеспечения совместимости с микроконтроллерами, который возможно появятся в будущем, всегда записывайте этот бит в 0, когда записываете UCSRnA. Флаг DORn очищается, когда принятый фрейм успешно перемещен из регистра сдвига в буфер приема.
Флаг ошибки четности Parity Error (UPEn) показывает, что следующий фрейм, находящийся в буфере приема, имеет ошибку четности на приеме. Если контроль четности не разрешен, то бит UPEn будет всегда читаться как 0. Для обеспечения совместимости с микроконтроллерами, который возможно появятся в будущем, всегда сбрасывайте этот бит в 0, когда пишете в UCSRnA.
Узел проверки бита четности (Parity Checker) активен, когда установлен в 1 бит USART Parity mode (UPMn1). Тип выполняемой проверки на четность (нечетность odd или четность even) выбирается битом UPMn0. Когда проверка четности разрешена, Parity Checker вычисляет четность от бит данных приходящих фреймов, и сравнивает результат с битом четности из последовательного фрейма. Результат проверки сохраняется в буфере приема вместе с принятыми данными и stop-битами. Флаг Parity Error (UPEn) может быть прочитан программно, чтобы проверить, была ли во фрейме ошибка четности.
Бит UPEn установится, если в следующем символе, который можно прочитать из буфера приема, была ошибка четности на приеме, и проверка четности в этот момент была разрешена (UPMn1 = 1). Этот бит действителен, пока не произойдет чтение буфера приема (регистра UDRn).
Запрет приемника. В отличие от передатчика, запрет приемника срабатывает немедленно. Таким образом, принимаемый в настоящий момент фрейм данных (и конечно последующие после запрета) будут потеряны. Когда приемник запрещен (т. е. RXENn сброшен в 0), то он больше не переназначает нормальную работу порта RxDn как ножки GPIO. При запрете приемника буфер FIFO приемника будет сброшен, все оставшиеся в нем непрочитанные данные будут потеряны.
Сброс буфера приема. Буфер FIFO приемника будет сброшен, когда приемник запрещен, т. е. запомненные в буфере данные уничтожаются, непрочитанные данные будут потеряны. Если нужно сбросить буфер во время нормальной работы, например по причине события ошибки, просто делайте чтение UDRn, пока флаг RXCn не очистится. В следующем примере кода показана очистка буфера приема.
USART_Flush:
sbis UCSRnA, RXCn
ret
in r16, UDRn
rjmp USART_Flush
void USART_Flush( void )
{
unsigned char dummy;
while ( UCSRnA & (1 << RXCn) )
dummy = UDRn;
}
[Асинхронный прием данных]
В состав USART включены блоки восстановления тактов (Asynchronous Clock Recovery) и данных (Asynchronous Data Recovery), чтобы поддержать асинхронный прием данных. Логика восстановления используется для синхронизации генерируемых внутри тактов скорости (baud rate) для входящих асинхронных последовательных фреймов на выводе RxDn. Логика восстановления данных оцифровывает и пропускает через ФНЧ каждый бит приходящих данных, чтобы улучшить стойкость приемника к помехам. Диапазон работоспособности асинхронного приема зависит от точности внутренних тактов скорости, скорости входящих фреймов, размера фрейма в количестве бит.
Asynchronous Clock Recovery. Логика восстановления тактов синхронизирует внутренние такты по входящим последовательным фреймам. На рис. 22-5 показан процесс оцифровки стартового бита входящего фрейма. Частота оцифровки в 16 раз больше частоты бит (baud rate) для нормального режима (Normal mode), и в 8 раз больше частоты бит для режима двойной скорости (Double Speed mode). Горизонтальные стрелки показывают интервалы подстройки синхронизации в процессе оцифровки. Обратите внимание на увеличенные интервалы для режима двойной скорости (Double Speed mode, U2Xn = 1). Выборки, помеченные нулями, означают выборки, когда сигнал RxDn в состоянии ожидания idle (т. е. нет активной передачи).
Рис. 22-5. Выборка (оцифровка) start-бита.
Когда логика восстановления тактов детектировала переход от лог. 1 (idle) к лог. 0 (start) на линии RxDn, инициируется последовательность детектирования start-бита. Выборка 1 на рисунке показывает первую нулевую выборку. Затем логика восстановления тактов использует выборки 8, 9 и 10 для нормального режима, и выборки 4, 5 и 6 для режима двойной скорости (эти цифры выделены прямоугольной рамкой на рисунке), чтобы определить, что действительно принят допустимый start-бит. Если 2 или большее количество этих выборок имеют лог. 1 (принцип большинства), то start-бит отбрасывается как шумовая помеха, и приемник снова начинает детектирование следующего перехода от 1 к 0. Однако если детектирован допустимый start-бит ("большинство" указывает на 0), то в логика восстановления тактов синхронизируется, и может начаться процесс восстановления данных. Процесс синхронизации повторяется для каждого start-бита.
Asynchronous Data Recovery. Когда произошла синхронизация тактов приемника по start-биту, может начать работу восстановление данных. Блок восстановления данных использует машину из 16 состояний для каждого бита в нормальном режиме и машину 8 состояний для режима двойной скорости. На рис. 22-6 показана оцифровка битов данных и бита четности (BITn). Каждая выборка помечена цифрой, которая равна состоянию блока восстановления.
Рис. 22-6. Выборка данных и бита четности.
Принятие решения о лог. уровне принятого бита выполняется по тому же самому "принципу большинства" на 3 выборках посередине принимаемого бита. Номера этих выборок помечены на рисунке рамочками. Если 2 или большее количество из этих 3 выборок прочитаны как 1, то принятый бит регистрируется как лог. 1. И аналогично если 2 или большее количество из этих 3 выборок прочитаны как 0, то принятый бит регистрируется как лог. 0. Этот принцип работает как простейший цифровой ФНЧ для входящего сигнала на выводе RxDn. Процесс восстановления данных повторяется для каждого бита, пока не завершится прием всего фрейма, включая первый stop-бит. Имейте в виду, что приемник использует только первый stop-бит фрейма.
На рис. 22-7 показана оцифровка stop-бита как можно раньше относительно начала start-бита следующего фрейма.
Рис. 22-7. Выборка стоп-бита и следующего стартового бита.
Для оцифровки (получения значения) stop-бита применяется тот же самый мажоритарный принцип голосования, как и для других бит фрейма. Если определено, что stop-бит равен лог. 0, то регистрируется ошибка фрейма, и будет установлен флаг Frame Error (FEn).
Новый переход 1 -> 0 покажет начало start-бита нового фрейма, и он может появиться сразу после последнего бита, в котором использовалось детектирование уровня по мажоритарному принципу. Для режима Normal Speed, первая выборка с низким уровнем может быть в точке, промаркированной как (A) на рис. 22-7. Для Double Speed mode первый низкий уровень должен быть задержан до (B). (C) помечает stop-бит полной длины. Раннее детектирование start-бита влияет на рабочий диапазон приемника (Asynchronous Operational Range).
Asynchronous Operational Range. Рабочий диапазон приемника зависит от несоответствия скорости принимаемых бит и генерируемой внутри скорости. И передатчик, и приемник должны быть настроены на одну и ту же скорость, но из-за погрешности частоты системного тактового генератора реальные частоты могут отличаться. Если передатчик посылает фреймы со слишком большой частотой бит или слишком малой частотой бит, или если генерируемая частота бит приемника имеет отличающуюся базовую частоту (см. таблицу 22-2), то приемник не сможет синхронизировать фреймы по start-биту.
Следующие формулы можно использовать для вычисления соотношения между скоростью принимаемых данных и внутренней скоростью приемника.
(D + 1) * S Rslow = ---------------------- S - 1 + D*S + SF |
|
|
(D + 2) * S Rfast = ---------------------- (D + 1) * S + SM |
D сумма числа бит символа и бита четности (D = 5 .. 10 бит).
S количество выборок на бит, S = 16 для Normal Speed mode и S = 8 для Double Speed mode.
SF номер первой выборки, используемой для детектирования уровня по мажоритарному принципу. SF = 8 для Normal Speed mode и SF = 4 для Double Speed mode.
SM номер средней выборки, используемой для детектирования уровня по мажоритарному принципу. SM = 9 для Normal Speed mode и SM = 5 для Double Speed mode.
Rslow соотношение между самой низкой входной скоростью и собственной скоростью приемника, при котором приемник все еще может принимать данные.
Rfast соотношение между самой высокой входной скоростью и собственной скоростью приемника, при котором приемник все еще может принимать данные.
Таблицы 22-2 и 22-3 дают список максимально допустимой ошибки baud rate приемника. Обратите внимание, что для Normal Speed mode допуск больше.
Табл. 22-2. Рекомендуемые максимальные скорости передачи и погрешность приемника для нормального режима скорости (U2Xn = 0).
D (Data + Parity Bit) |
Rslow (%) |
Rfast (%) |
MAX общая ошибка, % |
Рекомендуемая MAX ошибка приемника, % |
5 |
93.20 |
106.67 |
+6.67 / -6.8 |
±3.0 |
6 |
94.12 |
105.79 |
+5.79 / -5.88 |
±2.5 |
7 |
94.81 |
105.11 |
+5.11 / -5.19 |
±2.0 |
8 |
95.36 |
104.58 |
+4.58 / -4.54 |
±2.0 |
9 |
95.81 |
104.14 |
+4.14 / -4.19 |
±1.5 |
10 |
96.17 |
103.78 |
+3.78 / -3.83 |
±1.5 |
Табл. 22-3. Рекомендуемые максимальные скорости передачи и погрешность приемника для двойной скорости (U2Xn = 1).
D (Data + Parity Bit) |
Rslow (%) |
Rfast (%) |
MAX общая ошибка, % |
Рекомендуемая MAX ошибка приемника, % |
5 |
94.12 |
105.66 |
+5.66 / -5.88 |
±2.5 |
6 |
94.92 |
104.92 |
+4.92 / -5.08 |
±2.0 |
7 |
95.52 |
104.35 |
+4.35 / -4.48 |
±1.5 |
8 |
96.00 |
103.90 |
+3.90 / -4.00 |
±1.5 |
9 |
96.39 |
103.53 |
+3.53 / -3.61 |
±1.5 |
10 |
96.70 |
103.23 |
+3.23 / -3.30 |
±1.0 |
Рекомендации по максимальной ошибке baud rate приемника были сделаны на основе предположения, что и приемник, и передатчик разделяют одинаковую максимальную погрешность частоты.
Есть 2 возможных источника ошибок baud rate приемника. Системная тактовая частота приемника (XTAL) всегда будет незначительно зависеть от напряжения питания и температуры окружающей среды. Когда для генерации системной частоты используется кварц, то в этом случае проблем чаще всего не будет. Однако если применить некачественный резонатор с допуском более 2%, то это может послужить причиной ошибок. Второй источник ошибки более управляемый. Генератор baud rate не всегда делает точное деление системной частоты, чтобы получить желаемое значение baud rate. В этом случае желательно использовать то значение для UBRR, которое дает ошибку как можно меньше.
[Multi-processor Communication Mode]
Установка бита Multi-processor Communication mode (MPCMn) в регистре UCSRnA разрешает функцию фильтрации входящих фреймов, полученных приемником USART. Фреймы, которые не содержат информацию адреса, будут игнорироваться и не попадут в буфер приема. Это эффективно уменьшит количество входящих фреймов, которые должны быть программно обработаны CPU в системе, где несколько процессоров (MCU) обмениваются данными по одной и той же последовательной шине данных. На передатчик не влияет установка бита MPCMn, но передатчик должен использоваться по-другому, когда он работает как часть системы, использующей Multi-processor Communication mode.
Если приемник настроен для приема фреймов, содержащих от 5 до 8 бит данных, то первый stop-бит показывает, есть ли во фрейме информация адреса. Если приемник настроен на фреймы с 9 битами данных, то 9-й бит (RXB8n) используется для идентификации фреймов адреса и данных. Когда бит типа фрейма (это первый stop-бит или 9-й бит) равен 1, то фрейм содержит адрес. Когда бит типа фрейма равен 0, то это будет фрейм данных.
Multi-processor Communication mode разрешает нескольким подчиненным MCU принимать данные от главного MCU. Это осуществляется путем декодирования фрейма адреса, чтобы определить, какой именно MCU адресован на шине. Если адресован конкретный подчиненный MCU, то он примет следующие фреймы данных как обычно, в то время другие подчиненные MCUs будут игнорировать принятые фреймы, пока не будет принят другой адресный фрейм.
Использование MPCMn. Для MCU, который работает как главный на общей шине, можно использовать 9-битный формат фрейма (UCSZn = 7). Девятый бит (TXB8n) должен быть установлен, когда передается фрейм адреса (TXB8n = 1), или очищен, когда передается фрейм данных (TXB = 0). Подчиненные MCU в этом случае должны быть настроены для использования 9-битного формата фрейма.
Для обмена данными в Multi-processor Communication mode должна использоваться следующая процедура:
1. Все подчиненные MCU настроены в Multi-processor Communication mode (установлен бит MPCMn в регистре UCSRnA).
2. Главный MCU посылает фрейм адреса, и все подчиненные устройства принимают и читают этот фрейм. В подчиненных MCU флаг RXCn в регистре UCSRnA будет установлен как обычно.
3. Каждый подчиненный MCU читает регистр UDRn, чтобы определить, что для приема выбран именно он (проверяет совпадение адреса). Если так, то он очищает бит MPCMn в регистре UCSRnA, в противном случае просто ждет следующего адресного фрейма, сохраняя установленным бит MPCMn.
4. Адресованный MCU будет принимать все фреймы данных, пока не поступит новый фрейм адреса. Другие подчиненные MCUs, у которых установлен бит MPCMn, будут (аппаратно) игнорировать фреймы данных.
5. Когда адресованный MCU примет последний фрейм данных, то он устанавливает бит MPCMn и ждет новый фрейм адреса от главного MCU. Затем процедура повторяется начиная с шага 2.
Можно использовать любой формат фрейма от 5 до 8 бит, но это непрактично, потому что приемник нужно перепрограммировать между использованием n и n+1 форматом бит фрейма. Это делает полнодуплексный обмен сложным, потому что передатчик и приемник используют настройку для одного и того же размера символа. Если используется формат символа от 5 до 8 бит, то передатчик должен быть установлен на использование двух stop-битов (USBSn = 1), поскольку первый stop-бит используется для указания типа фрейма (адрес или данные).
Не используйте инструкции ассемблера Read-Modify-Write (SBI и CBI) для установки или очистки бита MPCMn. Бит MPCMn использует то же самое место в пространстве I/O, как и флаг TXCn, и это может случайно очистить его при использовании инструкций SBI или CBI.
Комментарии
microsin: прочитайте внимательно статью, в ней все описано, даже с примером кода.
RSS лента комментариев этой записи