Universal Asynchronous Receiver-Transmitter — Универсальный асинхронный приемо-передатчик
Схема подключения:
Rx<-Tx
Tx->Rx
GND<->GND
Вероятно один из старейших и весьма простой интерфейс передачи данных.
В начальный момент шина притянута к лог. 1 (через резистор в ~10k)
при старте передачи передающее устройство притягивает шину к GND.
после начинает выдавать биты данных, удерживая их уровень строго определенное время, которое зависит от скорости передачи.
Длинна поля данных обычно 8 или 9 бит.
Также есть битовое поле четности (Parity) оно м.б. none/even/odd (отсутствует/четная/нечетная)
Если поле выбрано, то этот бит выставляется чтобы сумма бит была четной/нечетной.
Оканчивается посылка притяжкой линии в лог. 1.
Создадим проект в STM32CubeMX, выберем USART1 и сделаем настройки как на рисунке
Во вкладке NVIC выберем «USART1 Global Interrupt».
Сгенерируем проект.
Для UART есть блокирующие функции передачи и приема — после их вызова контроллер выполняет только их (или задачу с более высоким приоритетом)
Блокирующая передача:
HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
Блокирующий прием:
HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
Достаточно удобно использовать huart1.RxXferCount — счетчик принятых байт (глобальная переменная HAL)
Прием и пеердача по UART с использованием прерываний
Передача по прерыванию:
HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
Прием по прерыванию:
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
При использовании прерывания удобно после инициализации UART делать HAL_UART_Receive_IT на 1 байт, а в файле stm32f1xx_it.c
в функции USART1_IRQHandler производить обработку (парсинг) сообщения
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
parser();
HAL_UART_Receive_IT(…);
/* USER CODE END USART1_IRQn 1 */
}
Если необходимо передавать большие объемы данных в т.ч. на низкой скорости, то для UART можно использовать DMA (контроллер прямого доступа к памяти), в этом случае передача бит данных идет в обход АЛУ через DMA, что существенно разгружает систему.
Настройки DMA приведены на рисунке.

Для одного микроконтроллера можно использовать несколько каналов DMA с разными приоритетами, также можно изменять размер «кадра»данных, но чаще всего используется байт.
Передача с использованием DMA:
HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
Прием с использованием DMA:
HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

