Меню Закрыть

UART/USART

USART Universal Synchronous/Asynchronous Receiver/Transmitter — Это универсальный синхронный/асинхронный приёмопередатчик. Из названия понятно что это некий интерфейс для передачи и приема данных между цифровыми устройствами. 

Важным моментом является асинхронность, т.е. нет никакого тактового сигнала от другого устройства чтобы знать когда считывать биты. Поэтому между устройствами нужна согласованность по скорости, называемая бод рейтом.В упрощённом виде идея такая. К приемнику приходит байт данных со всеми стартовыми стоповыми битами, и за определённый промежуток времени он считывается, при этом из за согласованности по скорости приемник точно знает  какой момент времени соответствует нужному биту.

Пройдёмся по основным регистрам, режимам работы, реализуем на практике некоторые устройства.

Основные регистры USART.

Всего их 7 штук. Рассмотрим подробнее каждый.

1)USART_SR (Status Register) – Регистр состояния.Содержит флаги состояния передачи и приёма.

Флаги:

TXE — Transmit Data Register Empty.Флаг буфер передачи пуст.

TC (бит 6) — Transmission Complete. Флаг полного завершения передачи.

RXNE — Read Data Register Not Empty. Флаг принятого байта.

И есть ещё флаги ошибок NE, FE, PE,ORE


2)USART_DR (Data Register) — Регистр данных. Можно сказать основной регистр при работе USART. Сюда записываем что хотим передать, отсюда же забираем то что получили.И хотя регистр один, но приём и передача могут происходить одновременно. Это происходит за счет внутреннего разделения на разные сдвиговые регистры.


3)USART_BRR (Baud Rate Register) — Регистр скорости передачи. В этом регистре настраиваем скорость передачи. Измеряется она в бодах. Важно чтобы у приёмника и передатчика она совпадала. Допускается лишь небольшое отклонение в несколько процентов, иначе точная работа не гарантирована.


4)USART_CR1 (Control Register 1) — Регистр управления 1.

Основные биты:

UE —  USART Enable (включение USART).

M —  Word length: 0 = 8 бит, 1 = 9 бит.

PCE —  Parity Control Enable (включение бита чётности).

PS — Parity Selection: 0 = чётная, 1 = нечётная.

TXEIE — разрешение прерывания по TXE.

RXNEIE — разрешение прерывания по RXNE.

TE — Transmitter Enable (разрешение передачи).

RE — Receiver Enable (разрешение приёма).


5)USART_CR2 (Control Register 2) — Регистр управления 2

Основные биты:

STOP — количество стоп-битов:

CLKEN — включение линии тактового сигнала (для синхронного режима).

CPOL, CPHA — полярность и фаза тактового сигнала.


6)USART_CR3 (Control Register 3) — Регистр управления 3

В этом регистре биты настройки DMA.


7)USART_GTPR (Guard Time and Prescaler Register)- биты, отвечающие за предделитель.

Формат кадра USART.

В неактивном режиме выход передатчика UART находится в высоком состоянии;

Передача байта начинается со стартового бита, который всегда равен 0 (низкий уровень сигнала).С момента приёма начинается внутренний отсчет.

Дальше идут биты данных.(0-7)

Опционально может быть бит четности(один или два).При отправке в этот бит записывается единица или ноль в зависимости от количества единичек в предыдущих восьми битах. Если единичек чётное кол-во, то записывается 0, если нечетное, то 1.

Передача данных заканчивается стоповым битом, который равен 1 (высокий уровень сигнала).

Посылка выглядит так:

стартовый бит — биты данных-бит четности-стоповый бит

Для интерфейса UART существуют стандартные скорости передачи данных(baud rate).Наиболее часто используемые стандартные значения включают 4800, 9600, 19200, 38400, 57600, 115200 бод. Чем выше baud rate тем больше скорость передачи, но выше вероятность ошибок.

Схема подключения.

Схема подключения достаточно простая, необходимо всего два провода. Tx(transmit) линия, по которой устройство отправляет данные.Rx(receive) линия, по которой устройство принимает данные.Соединение соответственно Tx первого устройства с Rx второго Rx первого устройства c Tx второго.

USART это интерфейс точка точка, т.е. в основном он рассчитан на два устройства.Если вам нужно несколько ведомых устройств лучше выбрать SPI или I2C.

Практическая реализация

Я использую плату STM32F4 Discovery , на ней имеется 6 штук USART. Давайте подключим USART2 к USART3 и передадим данные и выведем их на дисплей.

Параметры у обоих USART выставляем следующие.Для корректной работы важно чтобы они были одинаковые.

Baud Rate 115200 Bits/s — скорость передачи

Word Length — 8 Bits — длина нашей посылки

Parity — без бита четности

Stop Bits — количество стоп битов, пусть будет 1

Не забудьте включить прерывания.

Генерируем наш код с помощью CubeIde.Видим что функции инициализации USART уже готовы.

MX_GPIO_Init();
MX_USART2_UART_Init();
MX_USART3_UART_Init();

Для передачи данных воспользуемся функцией 

HAL_UART_Transmit_IT(&huart2, txData, sizeof(txData) - 1);

&huart2 — указатель на структуру UART, со всеми параметрами

txData — массив со строкой

sizeof(txData)-1 — размер буфера минус чтобы не отправлять нулевой терминатор

Аналогично функция приёма

HAL_UART_Receive_IT(&huart3, rxData, sizeof(txData) - 1);

Добавим начальные переменные

uint8_t txData[] = "Hello from USART"; // что будем отправлять
uint8_t rxData[sizeof(txData)]; // буфер для приёма

В секции USER CODE BEGIN 4 добавим колбеки для наглядной проверки что передача и приём состоялись. 

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART2) // проверяем, что это именно USART2
    {
        // Например, включим светодиод по завершении передачи
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
    }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART3)
    {
        HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);
        HAL_UART_Receive_IT(&huart3, rxData, sizeof(txData) - 1);
    }
}

Они срабатывают в момент прерывания по передаче и приёму соответственно. После окончания передачи включим светодиод на PIND12, а после окончания приёма на PIND13, и снова запустим нашу функцию приёма. Для наглядности можно вывести в терминал либо подключить дисплей. Как подключить дисплей в этой статье https://beartronix.com/ru/st7735

Как подключить терминал по UART можно почитать здесь https://beartronix.com/ru/pl2303hx-usb-uart

Нам остается только вызвать наши функции и проверить работу.

HAL_UART_Receive_IT(&huart3, rxData, sizeof(txData) - 1);
HAL_UART_Transmit_IT(&huart2, txData, sizeof(txData) - 1);
ST7735_FillScreen(ST7735_BLACK); // очищаем экран
HAL_Delay(2000);
ST7735_DrawString(0, 0, (char*)rxData, Font_11x18, ST7735_GREEN, ST7735_BLACK);

Видим что диоды горят а на дисплее надпись, что говорит о том что мы успешно передали данные по UART.

В итоге мы разобрались с устройством и принципами работы интерфейса USART, рассмотрели его основные регистры и форматы кадров, а также реализовали практический пример передачи и приёма данных между двумя модулями на STM32F4 Discovery. Используя функции HAL с поддержкой прерываний, мы смогли настроить двусторонний обмен, проверить его работоспособность с помощью светодиодов и вывести результат на дисплей. Такой подход позволяет не только понять основы работы UART/USART, но и получить практический навык, который пригодится при разработке реальных проектов с микроконтроллерами.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *