STM32 UART Communication Guide: Transmit, Receive, & Interrupts
If you’ve ever tried sending data between your STM32 and another device, you’ve probably met UART. The problem? Many beginners face errors like missing bytes, unstable baud rates, or code that just won’t work. This can waste hours of your time and slow your project. The good news is you can learn UART communication with STM32 HAL in a simple way. In this guide, you’ll see how to set up UART transmit, receive, and interrupts for STM32 boards — including STM32F103, STM32F4, and STM32 Nucleo — so you can send and receive data reliably.
What is UART Communication in STM32?
UART (Universal Asynchronous Receiver-Transmitter) is a way for two devices to send and receive data without a shared clock. STM32 microcontrollers include hardware UART modules, and the STM32 HAL library makes them easier to use. You can use UART for:
- Debugging with a USB-to-Serial adapter
- Talking to GPS modules, sensors, or other MCUs
- Single-wire protocols like LIN
UART is different from SPI or I2C — it uses fewer wires and is asynchronous.
STM32 UART Basics
Before coding, it helps to know the basics:
- TX pin: Sends data
- RX pin: Receives data
- Baud rate: Speed of communication (e.g., 9600, 115200)
- Data bits, parity, stop bits: Define how bits are framed
In STM32 HAL, the HAL_UART_Transmit
and HAL_UART_Receive
functions handle basic communication.
Setting Up STM32 UART in CubeMX
- Open CubeMX and select your board (STM32F103, STM32F4, STM32 Nucleo).
- Enable USART in “Connectivity” settings.
- Set Baud Rate (e.g., 115200).
- Select Word Length, Parity, Stop Bits.
- Enable NVIC interrupts if using UART interrupt mode.
- Generate the code.
This gives you a HAL-based UART setup.
UART Transmit with STM32 HAL
The simplest way to send data is with HAL_UART_Transmit
.
char msg[] = "Hello, STM32!";
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
Notes:
&huart1
is the UART handle from CubeMX.- Timeout can be a number in milliseconds or
HAL_MAX_DELAY
.
UART Receive with STM32 HAL
You can receive data in blocking mode:
uint8_t buffer[10];
HAL_UART_Receive(&huart1, buffer, 10, HAL_MAX_DELAY);
Problems with blocking mode:
- MCU waits until all bytes arrive.
- Not good for continuous data streams.
UART Interrupt Mode
Interrupt mode lets the MCU do other tasks while waiting for data.
uint8_t rx_byte;
HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
In your interrupt callback:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
}
}
UART Idle Line Detection
For variable-length data, idle line detection is better than fixed-size buffers.
Steps:
- Enable
UART_IT_IDLE
interrupt. - In
HAL_UART_IdleLineCallback
, process the received buffer. - Reset the DMA or interrupt reception.
Single-Wire UART (One-Wire Protocol)
You can use the same pin for TX and RX:
- Set TX as open-drain.
- Use an external pull-up resistor.
- Switch between TX and RX in software.
LIN Protocol with STM32
LIN (Local Interconnect Network) is a single-wire protocol often used in automotive. STM32 supports LIN mode:
- Enable LIN mode in CubeMX.
- Use
HAL_LIN_SendBreak
for sync.
STM32 UART Tips
- Match baud rates on both devices.
- Use DMA for high-speed data.
- Check your PCB wiring twice.
- Add small delays if needed when using printf.
Example: STM32F103 to USB Serial Monitor
- Connect TX to USB-to-Serial RX, and RX to TX.
- Common ground between STM32 and adapter.
- Set baud rate to 115200 in both CubeMX and serial monitor.
Common UART Problems and Fixes
Problem | Fix |
---|---|
Garbled text | Check baud rate and clock settings |
Data loss | Use DMA or interrupt mode |
Only first message sent | Check blocking code or missing HAL_UART_Transmit calls |
Interrupt not firing | Enable NVIC in CubeMX and HAL code |
FAQs
Who should use UART with STM32?
Anyone connecting STM32 to other devices like GPS, sensors, or PCs.
What is the fastest baud rate for STM32 UART?
Up to several Mbps depending on the MCU and clock settings.
Where is the UART pin on STM32 Nucleo?
Check the board’s pinout in the datasheet or CubeMX.
Why does my UART data look wrong?
Baud rate mismatch is the most common cause.
How can I send a string over UART?
Use HAL_UART_Transmit
with the string buffer.
Will UART work without a common ground?
No, a shared ground is needed for stable communication.
How do I handle long messages?
Use DMA or buffer them in interrupt mode.
What is UART idle line detection?
A method to detect the end of a message when length is unknown.
How do I debug UART issues?
Use an oscilloscope or logic analyzer to check the signal.
Can I use one pin for TX and RX in STM32?
Yes, with single-wire mode and hardware setup.
Conclusion
UART is one of the easiest ways to connect your STM32 to other devices. Using STM32 HAL functions, you can send and receive data in blocking, interrupt, or DMA modes. Idle line detection and single-wire configurations add more flexibility. Whether you use an STM32F103, STM32F4, or STM32 Nucleo, following these steps will help you avoid common mistakes and get reliable communication. If you found this guide useful, try it on your board today and share your results in the comments.