STM32 UART Interrupts Explained – Complete Guide

If you’ve worked with STM32 boards, you know UART communication is one of the most common tasks. But setting it up with interrupts can feel tricky, especially when dealing with idle line detection, single-wire UART, or protocols like LIN. Missing a single step can cause missed bytes, extra CPU load, or even complete communication failures. That’s why in this guide, we’ll walk through STM32 UART interrupts step-by-step, covering transmit, receive, idle detection, and special modes — all using STM32 HAL so you can adapt it to STM32F103, STM32F4, and STM32 Nucleo boards with ease.

What is UART Communication in STM32?

UART (Universal Asynchronous Receiver/Transmitter) is a simple, widely used serial communication protocol. STM32 microcontrollers include hardware UART/USART peripherals that handle data transmission and reception.

In STM32, UART can be used in:

  • Full-duplex mode (separate TX and RX lines)
  • Half-duplex mode (single-wire mode)
  • LIN protocol mode (for automotive systems)
  • Idle line detection (to detect the end of data streams)

Why Use UART Interrupts Instead of Polling?

Polling checks the UART status register repeatedly, which wastes CPU time. Interrupts trigger only when data is ready or a transmission is complete. This means:

  • CPU is free for other tasks
  • Reduced power usage in low-power modes
  • Higher reliability for continuous data streams

STM32 HAL Functions for UART Interrupts

When using STM32 HAL, you’ll mainly work with these functions:

  • HAL_UART_Receive_IT() – Start reception in interrupt mode
  • HAL_UART_Transmit_IT() – Start transmission in interrupt mode
  • HAL_UARTEx_ReceiveToIdle_IT() – Receive data until idle line detected
  • HAL_UART_IRQHandler() – Main interrupt handler (called inside IRQHandler)
  • HAL_UART_TxCpltCallback() – Called when transmit completes
  • HAL_UART_RxCpltCallback() – Called when receive completes

STM32 UART Interrupt Workflow

  1. Enable UART clock in CubeMX or manually in code.
  2. Configure UART pins for TX/RX (AF push-pull, pull-up if needed).
  3. Select baud rate, parity, word length, and stop bits.
  4. Enable interrupt in NVIC.
  5. Call HAL interrupt functions for receive/transmit.
  6. Handle callbacks to process received data or prepare the next transmission.

Example: Basic UART Receive Interrupt (STM32F103)

uint8_t rx_data;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart->Instance == USART1) {
        // Process received byte
        HAL_UART_Receive_IT(&huart1, &rx_data, 1); // Restart reception
    }
}

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_USART1_UART_Init();
    HAL_UART_Receive_IT(&huart1, &rx_data, 1); // Start reception
    while (1) {
        // Main loop tasks
    }
}

Example: UART Idle Line Detection (STM32F4)

Idle line detection is useful when data arrives in bursts.

uint8_t rx_buffer[64];
uint16_t rx_len = 0;

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
    if (huart->Instance == USART2) {
        rx_len = Size;
        // Process rx_buffer data
        HAL_UARTEx_ReceiveToIdle_IT(&huart2, rx_buffer, sizeof(rx_buffer));
    }
}

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_USART2_UART_Init();
    HAL_UARTEx_ReceiveToIdle_IT(&huart2, rx_buffer, sizeof(rx_buffer));
    while (1) {}
}

Example: Single-Wire UART (Half-Duplex Mode)

In single-wire mode, TX and RX share the same pin.

void MX_USART3_UART_Init(void) {
    huart3.Instance = USART3;
    huart3.Init.BaudRate = 115200;
    huart3.Init.WordLength = UART_WORDLENGTH_8B;
    huart3.Init.StopBits = UART_STOPBITS_1;
    huart3.Init.Parity = UART_PARITY_NONE;
    huart3.Init.Mode = UART_MODE_TX_RX;
    huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    HAL_HalfDuplex_Init(&huart3);
}

LIN Protocol with STM32 UART

LIN (Local Interconnect Network) uses UART hardware with special timing. In CubeMX, enable LIN Mode and set Break Detection Length.
Example:

HAL_LIN_SendBreak(&huart1);

Debugging UART Interrupt Issues

  • No data received? Check NVIC priority and that interrupts are enabled in CubeMX.
  • Garbage data? Mismatched baud rate between devices.
  • Only first byte received? Forgot to restart HAL_UART_Receive_IT() in callback.
  • Missed frames in idle detection? Increase buffer size or handle callback faster.

Performance Tips

  • Use DMA with interrupts for high-speed continuous data.
  • Keep callback functions short — just set flags and handle data in the main loop.
  • For low-power projects, combine UART interrupts with STOP mode wake-up.

STM32 Families Covered

This guide applies to:

  • STM32F103 – Affordable, widely used in Blue Pill boards
  • STM32F4 series – Faster cores, multiple UARTs with advanced features
  • STM32 Nucleo boards – Easy prototyping and USB-to-UART built-in

Common UART Interrupt Use Cases

  • Debug logging without blocking the main program
  • GPS data parsing with idle line detection
  • Half-duplex protocols for RS-485 or custom single-wire communication
  • LIN-based automotive sensor networks

Pros and Cons of UART Interrupts

Pros:

  • Low CPU usage compared to polling
  • Reliable for burst data
  • Easy to handle multiple UARTs

Cons:

  • Slightly more complex than polling
  • Requires careful buffer management

FAQ

1. What is UART interrupt in STM32?
It’s a hardware signal that tells the CPU when UART has sent or received data.

2. How do I enable UART interrupt in STM32 HAL?
Use HAL_UART_Receive_IT() or HAL_UART_Transmit_IT() and enable the NVIC interrupt.

3. Which STM32 function detects idle line?
HAL_UARTEx_ReceiveToIdle_IT() detects when the line is idle.

4. Can I use DMA with UART interrupts?
Yes, it’s common for high-speed continuous data.

5. What is the difference between polling and interrupt UART?
Polling checks constantly; interrupts wait for an event.

6. How many UARTs do STM32F103 chips have?
Usually 3, but it depends on the exact model.

7. Is single-wire UART supported in STM32?
Yes, via half-duplex mode.

8. Can STM32 handle LIN protocol?
Yes, with built-in LIN mode in many UART peripherals.

9. Why do I only get the first byte in UART receive interrupt?
You must restart HAL_UART_Receive_IT() in the callback.

10. Will UART interrupts work in low-power mode?
Yes, if configured as a wake-up source.

Conclusion

UART interrupts in STM32 save CPU time, improve responsiveness, and open the door to advanced features like idle detection, single-wire communication, and LIN protocol. By using HAL functions like HAL_UART_Receive_IT() and HAL_UARTEx_ReceiveToIdle_IT(), you can build efficient, non-blocking serial communication for STM32F103, STM32F4, and STM32 Nucleo boards.

If you found this guide helpful, share it with other embedded developers or drop your questions in the comments — and check ControllersTech for more STM32 tutorials.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

© 2025 Biz DirectoryHub - Theme by WPEnjoy · Powered by WordPress