Я використовував STM32CubeMx / HAL в декількох проектах зараз і виявив, що програмне забезпечення для обробки UART, яке він створює, має певні недоліки на стороні прийому.
Під час передачі, як правило, ви хочете надіслати блок даних або рядок тексту. У цьому випадку ви наперед знаєте, скільки триває передача даних, і тому використання DMA - очевидне рішення. Ви отримуєте переривання, коли передача завершена, і можете скористатися функцією зворотного виклику UART TX завершити, щоб вказати вашому головному коду, що передача завершена, і ви можете надіслати ще один блок даних.
Що стосується прийому даних, то функції, передбачені ST, передбачають, що ви знаєте, скільки символів надасть вам пристрій, що надсилає, перш ніж він почне надсилати. Зазвичай це не відомо. Функціональність переривання розміщує отримані дані в буфер і вказує лише на те, що є дані, коли отримано заздалегідь задану кількість символів. Якщо ви спробуєте використовувати функцію DMA або перервати функціональність для отримання даних, встановивши послідовні передачі одного символу, то час настройки для кожного з них означатиме, що ви втратите символи за будь-яким іншим, ніж найповільніші швидкості передачі даних (швидкість передачі даних, яку ви будете мати Початок втрати даних буде залежати від тактової частоти процесора) і надмірно завантажить процесор, не залишаючи циклів інструкцій для будь-якої іншої обробки
Щоб обійти це питання, я написав власну функцію обробника переривань, яка зберігає дані в невеликому локальному круговому буфері і встановлює кількість, яка читається основним кодом (RTM-рахунковий семафор), щоб вказати, що отримані дані готові. Основний код може потім збирати дані з цього буфера у вільний час, неважливо, чи є певна затримка в зборі даних, якщо локальний буфер не переповнюється до збору даних.