UART для передачи использует два
провода, один на прием, другой
на передачу. Поэтому протокол
является полнодуплексным. Однако,
регистр данных UDR один.
Работа с UART через прерывания мне показалась более эффективной нежели через циклы ожидания. Потому что, программа кроме того что принимает или передает что-либо через UART, она, как правило, занята еще какими-то задачами, будь то опрос датчиков или вывод информации на дисплей. И в таком случае возникает совсем не простая проблема эффективного переключения между задачами. И если, например, ожидание приема корректных данных затянется то микроконтроллер по сути подвиснет. Делать прерывание ожидания по таймауту, это лишний код которого можно избежать, если реализовать рабту с UART через прерывания. Ниже приведен исходник эхо-программы которая читает строку через UART и посылает ее обратно. Строка должна оканчиваться символом двоеточия. В программе используется USART_RXC вектор, который срабатывает когда на порт что-то поступило. Обработчик прерывания это "что-то" переносит в рабочий буфер. Если принятый байт является символом двоеточия, то устанавливается флаг done, по которому главная программа понимает что были приняты какие-то данные. Конечно, следовало бы принятую строку заносить в сетк, но в данном случае решил исходник не усложнять.
Работа с UART на ATmega несколько проще чем с таймерами, но на мой взгляд, в целом эта тема более мутная, хотя и более интересная. Зависит от того, с какой стороны посмотреть.
Так же как и с таймерами, для работы c USART имеется набор прерываний:
и регистров: