DTE - Data Terminal Equipment - ПЕРЕДАТЧИК
DСE - Data Circuit-Terminating Equipment - ПРИЕМНИК
115200 макс скорость, пакет макс 9бит (отклонение макс. частоты приемника / передатчика 10%)
Аппаратный контроль CTS / RTS
CTS - (Clear to send) - вход для разрешения Передатчику посылать данные. Передатчик ждет для передачи CTS = 0.
RTS Request to send - запрос COM-порта на передачу данных (сигнал COM-порта о готовности принимать данные).
DTR Data terminal ready - сигнал готовности COM-порта к обмену данными.
Data set ready - вход сигнала готовности от подключённого к порту устройства.
STM32407VE** (тренируемся - все на одной плате)
желтый и черный это RTS-CTS, CTS-RTS
зеленый и синий Tx-Rx, Rx-Tx
Для простоты - USART3 только передача, USART2 только прием. Гоним байты только в одну сторону. FreeRtos не используем. Все по минимуму.
Вариант 1: Работаем через прерывания HAL
Не скрою убито 2 дня. Поиски в интернете как ни странно не много дают. Но главное это логика и копание в исходниках HAL-а.
У нас с порта UART2 данные сразу шлются на UART3 того же контроллера!
Связка HAL_UART_Transmit_IT (HAL_UART_TxCpltCallback) , HAL_UART_Receive_IT (HAL_UART_RxCpltCallback) :
1. HAL_UART_Receive_IT и HAL_UART_Transmit_IT - это всего лишь команда к активации режима прерываний!
С предачей обычно все проще - мы знаем когда она начинается (мы начинаем передачу).
А вот прием вообще предположительно не понятный : когда , сколько байт придет непонятно (и придет ли вообще).
Поэтому рассмотрим прием отдельно:
HAL_UART_Receive_IT (..,rxBuf,toRead) HAL_UART_RxCpltCallback
По HAL_UART_Receive_IT активируется прием данных в НЕ блокирующем режиме , т.е. программа выполняется далее без блокировки.
Далее все зависит от механизма прерываний.
HAL_UART_RxCpltCallback вызывается из обработчика прерываний и тут мы смотрим сколько мы запросили принять toRead (в HAL_UART_Receive_IT ) и это есть RxXferSize и сколько приняли уже в буфер (rxBuf) это = RxXferSize - RxXferCount. Соответсвенно RxXferCount сколько еще осталось принять.
То есть RxXferCount уменьшается от toRead до 0 по мере поступления байтов.
Важно для понимания , что состояние порта становится сразу HAL_UART_STATE_BUSY_RX после HAL_UART_Receive_IT.
Так вот почему надо прием делать по 1 байту
Если запустить HAL_UART_Receive_IT (..,rxBuf,toRead) с toRead=2 и придет например 5 байт, то получится , что 2 байта HAL_UART_RxCpltCallback примет , а вот 3,4,5 байты где-то потеряются. Так как пока вы будете обрабатывать приход 2 байт , оставшиеся не будут ждать, они будут приходить , но их никто не будет ждать и принимать.
По-этому ВАЖНО в HAL_UART_RxCpltCallback обработчике прерываний сразу запускать прием следующих байт, после получения запрошенных. Но поскольку оперативно мы не можем знать сколько еще должно придти , то проще принимать тупо по 1 байту и сразу запускать прием следующего.
И тут есть важный момент если мы запросим прием 1 байта, нам может прийти на самом деле и 3 байта (RxXferSize =3). Почему ?
Потому , что есть понятие интервала между 2 байтами. Если они идут подряд , значит прием продолжается пока не возникнет пауза между байтами больше какой-то величины.
Соответственно тут надо использовать кольцевой буфер, в который попадает весь прием. И извлекать из этого буфера принятые байты не мешая одновременному дальнейшему приему.
Callback functions
Не забывайте использовать HAL_UART_ErrorCallback и некоторые другие коллбеки , туда залетают полезные по информативности проблемы - переполнение и др.
Открытый проект как всегда прикладываю ниже
Сделан на открытой платформе Atollic TrueStudio
Далее Uart аппаратное управление CTS/RTS.
Файлы для скачивания
*
отркрытый полностью проект