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

Документация

Протокол 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;
        }

    }

}


Если у вас есть какие-то замечания по этому документу или что-то осталось непонятно, то вы можете оставить свой отзыв или вопрос

Комментарии (3)

avatar

mastertron

  • 15 Август 2011, 18:06

ответить

Спасибо! Да, инфы в нете хватает, но разные люди по разному доводят инфу. Вот щас дошло:)
avatar

ua3usy

  • 29 Август 2011, 09:14

ответить

наконецто хороший и понятный пример
avatar

megamaster

  • 30 Октябрь 2011, 20:27

ответить

В реальных проектах имеет смысл притянуть линию RX микроконтроллера к земле резистором 10k, чтобы она не собирала помехи из окружающей среды

Анонимная отправка сообщений запрещена! Пожалуйста зарегистрируйтесь