Użyłem STM32CubeMx / HAL w kilku projektach i odkryłem, że generowane przez niego oprogramowanie do obsługi UART ma wyraźne wady po stronie odbiorczej.
Podczas transmisji zwykle będziesz chciał wysłać blok danych lub wiersz tekstu. W takim przypadku wiesz z góry, jak długo trwa przesyłanie danych, więc użycie DMA jest oczywistym rozwiązaniem. Otrzymujesz przerwanie po zakończeniu przesyłania i możesz użyć funkcji oddzwaniania UART TX complete, aby wskazać kodowi głównemu, że transmisja została zakończona, i możesz wysłać kolejny blok danych.
Jeśli chodzi o odbiór danych, wszystkie funkcje zapewniane przez ST zakładają, że wiesz, ile znaków da ci urządzenie wysyłające, zanim zacznie wysyłać. Zwykle nie jest to znane. Funkcja przerwania umieszcza odebrane dane w buforze i wskazuje tylko, że dane są dostępne po otrzymaniu wstępnie zdefiniowanej liczby znaków. Jeśli spróbujesz użyć funkcji DMA lub funkcji przerwania do odbierania danych przez skonfigurowanie sekwencyjnego przesyłania pojedynczych znaków, to czas konfiguracji każdego z nich będzie oznaczał, że stracisz znaki przy czymkolwiek innym niż najniższa prędkość transmisji (prędkość transmisji, którą będziesz zaczną tracić dane będą zależeć od szybkości zegara procesora) i nadmiernie obciążą procesor, nie pozostawiając cykli instrukcji dla żadnego innego przetwarzania
Aby obejść ten problem, napisałem własną funkcję obsługi przerwań, która przechowuje dane w małym lokalnym buforze cyklicznym i ustawia liczbę odczytywaną przez kod główny (semafor zliczający RTOS), aby wskazać, że dane są gotowe. Główny kod może następnie gromadzić dane z tego bufora w dowolnym momencie, nie ma znaczenia, czy występuje pewne opóźnienie w gromadzeniu danych, pod warunkiem, że bufor lokalny nie przepełni się przed zebraniem danych.