UART (Universal Asynchronous Receiver-Transmitter) jest jednym z podstawowych interfejsów komunikacyjnych w mikrokontrolerach STM32. Umożliwia dwukierunkową wymianę danych między urządzeniami, przesyłając informacje kolejno, bit po bicie, w trybie asynchronicznym.

W praktyce elektroniki i robotyki komunikacja UART jest niezbędna w wielu zadaniach. Najczęstsze zastosowania to:

  • debugowanie i logowanie działania programu,
  • sterowanie urządzeniami peryferyjnymi lub modułami,
  • odbiór danych z czujników lub modułów pomiarowych,
  • komunikacja z komputerem PC.

Ten poradnik przygotuje cię do samodzielnej konfiguracji UART na STM32 – od ustawień pinów, przez parametry protokołu, aż po wysyłanie i odbieranie danych.

Czym jest UART i jak on działa?

UART to protokół komunikacji szeregowej, w którym dane transmitowane są sekwencyjnie, jeden bit po drugim. Protokół ten charakteryzuje się kilkoma istotnymi cechami:

  • interfejs dwukierunkowy – pozwala na jednoczesne wysyłanie i odbieranie danych;
  • osobne linie transmisji – każdy kierunek komunikacji używa oddzielnego pinu (TX do wysyłania, RX do odbioru);
  • komunikacja 1:1 – w podstawowej konfiguracji UART łączy dwa urządzenia jednocześnie;
  • tryb asynchroniczny – nie wymaga wspólnego sygnału zegarowego między nadajnikiem i odbiornikiem.

UART jest szczególnie przydatny, bo zapewnia prostą, niezawodną i tanią komunikację między mikrokontrolerem a komputerem PC.

Zasada połączenia TX i RX

Aby poprawnie połączyć dwa urządzenia komunikujące się przez UART, należy pamiętać o skrzyżowaniu linii TX i RX. Oznacza to, że:

  • pin TX (transmitter) pierwszego urządzenia łączysz z pinem RX (receiver) drugiego urządzenia;
  • pin RX pierwszego urządzenia łączysz z pinem TX drugiego urządzenia;
  • wspólna masa (GND) – połącz masy obu urządzeń, aby zapewnić prawidłowy poziom odniesienia sygnałów.

Takie połączenie gwarantuje, że dane wysyłane przez jedno urządzenie trafiają na wejście drugiego i odwrotnie.

UART w mikrokontrolerach STM32

Rodzina STM32 wyposażona jest w jeden lub więcej interfejsów UART/USART (Universal Synchronous/Asynchronous Receiver-Transmitter). Na przykład mikrokontroler STM32C031 posiada dwa interfejsy UART, podczas gdy większe modele mogą mieć ich więcej. Każdy interfejs należy adresować z numerem – na przykład USART2, USART3 itd.

W płytkach STM32 Nucleo UART podłączony do ST-Link jest wyprowadzony na piny PA2 (TX) i PA3 (RX), co umożliwia wygodną komunikację z komputerem przez jeden kabel USB.

Konfiguracja UART na STM32 – krok po kroku

1. Identyfikacja pinów

Pierwszym krokiem jest sprawdzenie w arkuszu danych (datasheet) mikrokontrolera, które piny obsługują wybrany interfejs. Dla STM32C031: USART2 korzysta z PA2 (TX) i PA3 (RX).

2. Włączenie zegarowania GPIO

Aby skonfigurować piny UART, najpierw włącz zegarowanie dla odpowiedniego portu GPIO poprzez RCC (Reset and Clock Control):

RCC->IOPENR |= RCC_IOPENR_GPIOAEN; // Włączenie zegarowania dla portu A

3. Konfiguracja alternatywnych funkcji pinów

Piny GPIO w STM32 mogą pełnić różne role. Aby wyprowadzić interfejs UART na piny, ustaw je jako funkcje alternatywne (Alternate Function):

void UART2_Config(void) {
RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
// Pin PA2 - TX (Alternate Function Mode)
GPIOA->MODER &= ~(GPIO_MODER_MODE2_0);
GPIOA->AFR |= GPIO_AFRL_AFSEL2_0;
// Pin PA3 - RX (Alternate Function Mode)
GPIOA->MODER &= ~(GPIO_MODER_MODE3_0);
GPIOA->AFR |= GPIO_AFRL_AFSEL3_0;
}

4. Włączenie zegarowania interfejsu UART

Po skonfigurowaniu pinów włącz zegarowanie dla samego interfejsu USART (to oddzielny blok sprzętowy):

RCC->APBENR1 |= RCC_APBENR1_USART2EN; // Włączenie USART2

5. Ustawienie parametrów transmisji

Parametry komunikacji UART dobiera się w rejestrach peryferium. Najczęściej stosowane ustawienia to:

  • 9600 bps – szybkość transmisji;
  • 8 bitów danych – standardowa długość słowa danych;
  • 1 bit stopu – zakończenie ramki danych;
  • bez bitu parzystości – brak kontroli parzystości;
  • bez sprzętowej kontroli przepływu – brak RTS/CTS;
  • tryb asynchroniczny – brak wspólnego zegara między urządzeniami.

Kluczową rolę odgrywa rejestr USARTx_BRR (Baud Rate Register), do którego wpisujesz wartość obliczoną ze wzoru z podręcznika referencyjnego (Reference Manual). Wartość zależy od częstotliwości taktowania interfejsu USART i docelowej prędkości transmisji.

Pamiętaj: prędkość (baud rate) oraz format ramki danych muszą być identyczne po obu stronach łącza.

Transmisja danych do komputera

Po poprawnej konfiguracji UART wysyłanie danych do komputera PC przebiega w kilku krokach:

  1. Włączenie transmitera – realizowane podczas konfiguracji;
  2. Wpisanie bajtu do rejestru nadawczego – TDR (Transmit Data Register);
  3. Kontrola gotowości nadajnika – sprawdzenie bitu TXFNF (Transmit FIFO Not Full), który powinien wynosić 1, co oznacza, że rejestr może przyjąć kolejne dane;
  4. Powtarzanie kroków 2–3 dla każdego wysyłanego bajtu.

Przykład kodu

Poniżej znajduje się prosty przykład, w którym co określony czas wysyłany jest bajt 'A’ do komputera:

int main(void)
{
// Konfiguracja SysTick Timer
SysTick_Config(12000000 / 1000);

// Inicjalizacja UART2
UART2_Config();

// Zmienne do zarządzania czasem
uint32_t Timer_UART = GetSystemTick();

/* Pętla główna */
while(1)
{
// Zadanie UART
if((GetSystemTick() - Timer_UART) > UART_TIMER)
{
// Ponowne załadowanie timera
Timer_UART = GetSystemTick();

// Wrzucenie bajtu 'A' do wysłania
USART2->TDR = 'A';

// Czekanie aż nadajnik będzie gotowy na kolejny bajt
while(!(USART2->ISR & USART_ISR_TXFNF));
}
}
return 0;
}

Konwersja USB-UART

W praktyce, do komunikacji między STM32 a komputerem PC często używa się konwertera USB–UART. Urządzenie to łączy się z pinami TX i RX mikrokontrolera oraz z GND, zamieniając sygnał szeregowy na USB rozpoznawane przez komputer.

W płytkach STM32 Nucleo problem ten rozwiązano fabrycznie – wbudowany ST-Link pełni funkcję konwertera i pozwala na komunikację oraz programowanie przez jeden kabel USB.

Odbieranie danych

Oprócz wysyłania UART pozwala na odbieranie danych z urządzeń zewnętrznych przy użyciu rejestru odbiorczego. W projektach wymagających wysokiej wydajności warto rozważyć DMA (Direct Memory Access), które przekazuje dane do pamięci bez blokowania głównej pętli programu.

Konfiguracja za pomocą STM32CubeMX

Dla początkujących alternatywą dla ręcznej konfiguracji rejestrów jest STM32CubeMX – graficzne narzędzie do konfiguracji mikrokontrolerów. W narzędziu tym wykonaj następujące kroki:

  1. Wyszukaj USART2 w sekcji „Connectivity”;
  2. Wybierz tryb Asynchronous – najprostszy dwuprzewodowy tryb transmisji;
  3. Wygeneruj automatycznie kod inicjalizacyjny.

Tryb asynchroniczny jest najczęściej używany, ponieważ nie wymaga dodatkowych linii kontroli przepływu i sprawdza się w większości zastosowań.