Вперед, только вперед...

Приёмопередатчик UART ATMega8

Источник: ATMega8

Протокол UART (Universal asynchronous receiver/transmitter) является одним из самых распространённых протоколов передачи данных между устройствами. Стандартный размер посылки при асинхронной передаче данных составляет 10 бит. Если по линии ничего не передаётся, то она находится в состоянии логической единицы. Передача начинается со стартового бита, который равен 0. Затем следуют 8 бит данных. Завершается передача стоп-битом, который равен 1.

На рисунке представлена передача байта 10000010

Для настройки и работы c UART в mega8 выделено 4 регистра:

1) Регистр управления UCSRB: разрешает/запрещает прерывания от UART, управляет функциями приёмопередатчика

2) Регистр состояния UCSRA

3) Регистр данных UDR - представляет собой 2 регистра, расположенных по одному адресу (1 регистр для передачи, 2 - для приёма данных)

4) Регистр UBRR отвечает за скорость передачи данных. Задаются значения младшего (UBBRL) и старшего (UBBRH) байтов регистра

5) Биты регистра UCSRC задают формат кадра

Регистр UCSRB

7 6 5 4 3 2 1 0
RXCIE TXCIE UDRIE RXEN TXEN CHR9 RXB8 TXB8

RXCIE=1 и прерывания разрешены (бит I=1 в регистре SREG) : прерывание по завершению приёма по UART разрешено

TXCIE=1 и прерывания разрешены (бит I=1 в регистре SREG) : прерывание по завершению передачи по UART разрешено

UDRIE=1 и прерывания разрешены (бит I=1 в регистре SREG) : прерывание по опустошению регистра данных UART разрешено

RXEN=1 : активация приёмника, вывод D0 становится входом UART.

TXEN=1 : активация передатчика, вывод D1 становится выходом UART.

CHR9=1 : длина передаваемой посылки с становится равной 11 бит (9 бит данных + старотовый бит + стоп-бит).

Регистр UCSRA

7 6 5 4 3 2 1 0
RXC TXC UDRE RXEN FE OR - -

Регист UCSRA информирует о состоянии UART

RXC=1: принятое слово данных перемещено из сдвигового регистра в регистр UDR. После чтения регистра UDR бит RXC сбрасывается в 0

TXC=1: символ в сдвиговом регистре передан полностью (включая стоп-бит), и из регистра UDR не ожидается новый байт данных.

UDRE=1: содержимое регистра UDR передано в сдвиговый регистр, т.е приёмопередатчик готов к передаче нового байта. Только после этого в UDR можно записывать новое значение. В противном случае можно потерять байт, который находился в UDR в ожидании отправки в сдвиговый регистр. Бит UDRE сбрасывается при записи данных в регистр UDR. При включении питания бит UDRE устанавливается в лог. 1.

FE=1: ошибка кадрирования. Ошибка кадрирования происходит, если стоп-бит не равен лог.1

OR=1: один из символов, переданный в UDR из сдвигового регистра не был прочитан перед поступлением следующего символа.

Настройка скорости передачи данных по UART

Скорость передачи данных по UART рассчитывается по формуле

f=Ф/(16(UBRR+1))

Ф - тактовая частота микроконтроллера

UBRR - значение регистра UBRR (состоит из значений младшего и старшего байтов UBBRH+UBBRL)

Таблица готовых значений UBBR для заданной частоты и скорости передачи данных

Значения скоростей передачи на передающим и принимающем устройствах должны совпадать! Также совпадать должны форматы передающихся кадров.

Формат кадра задаётся в регистре UCSRC

UCSRC.0 UCSRC.1 UCSRC.2 Формат кадра
0 0 0 Слово данных 5 бит
1 0 0 6 бит
0 1 0 7 бит
1 1 0 8 бит (стоит по умолчанию)
1 1 1 9 бит

В качестве примера рассмотрим следующий код. Он инициализирует UART микроконтроллера ATMega8 на скорости 9600 бит/сек и передаёт на терминал сообщение "ATMega8 UART Ready!". Далее в бесконечном цикле ведётся обработка сигналов, поступающих от терминала - если приходит '1', то лампочка, подключённая к биту 0 порта B загорается, если приходит '2' - лампочка гаснет.


int i;
int lng;
char mystr[]="Atmega8 UART ready!";
char rc;

void lampOFF()
{
PORTB.0=0;
}

void lampON()
{
PORTB.0=1;
}

void initUART()
{
UCSRB|=(1<<3)|(1<<4);
UBRRH=0x00;
UBRRL=0x33;
}

void main(void)

{
DDRB.0=1;
initUART();

lng=strlen(mystr);

for (i=0; i < lng; i++) {
while ( !( UCSRA & (1<<5)) ) {}
UDR=mystr[i];
}

while (1)
{
if ((UCSRA & (1<<7)))
{
rc=UDR;
}

switch (rc)
{
case '1': lampON(); break;
case '2': lampOFF(); break;
}

}

}
 
Еще одна статья - в отличии от этой - в ней работа UART четкая, что пришло то и ушло - без ошибок и искажений. Ссылка тут.
 

<< Вернуться на предыдущую страницу