STM32 UART DMA Reception

Introduction

When sending data via UART, we clearly know the timing and quantity of the data being sent, making it relatively straightforward to handle. However, the timing and quantity of data received via UART are often unknown, requiring more consideration in handling.

There are generally several methods to handle the issue of reception timing:

Polling: Regularly read the receive flag and immediately process the data if available;

Interrupt: Trigger an interrupt to notify the system when data arrives;

DMA: Automatically transfer data using DMA when it arrives.

The issue of reception quantity is essentially about when to stop receiving and process the data. If the quantity is known, reception can stop after receiving a specified amount, or a clear stop flag can be used to halt reception upon receiving specific flag data. The STM32 UART has an idle interrupt that can also serve as a stop signal. If using DMA, its half-receive interrupt and receive complete interrupt can be utilized to process data.

Using DMA

In some projects, an interrupt is triggered every time a data byte is received, and data is processed within the interrupt. While this method is better than polling, frequent interrupts can disrupt the main program’s execution, which is not a good design. If the processor has DMA, using DMA to transfer data and notifying the CPU to process it under certain conditions is a more reasonable and efficient approach. This article will introduce several methods for receiving UART data using DMA on the STM32. DMA reception generally requires preparing a receive buffer, with the DMA memory address being the starting address of the buffer and the reception quantity being the size of the buffer.

STM32 UART DMA Reception

The STM32 DMA can be set to circular mode, which automatically reloads the reception quantity and resets the reception address to the start of the buffer after the data to be received reaches zero, forming a circular buffer.

STM32 UART DMA Reception

The basic configuration of the UART and DMA is as follows:

STM32 UART DMA Reception

The method for processing data is shown below:

STM32 UART DMA Reception

Here, we check how much data has been received by DMA, whether there has been an overflow, and how to process the data, which depends on the project requirements.

1. Polling

This method involves continuously calling the usart_rx_check() function in the main loop, processing new data as it arrives.

STM32 UART DMA Reception

This method is only suitable for projects that perform this single task, or when it is absolutely certain that the time interval for calling this function will not fill the buffer. Otherwise, if processing is not timely, new data may overwrite unprocessed old data, leading to data loss.

2. Polling + RTOS

If an RTOS is available, a dedicated task can be created to handle reception, ensuring real-time processing of UART data without affecting the execution of other tasks, which is a reasonable approach.

STM32 UART DMA Reception

However, the UART reception task can consume a lot of CPU resources and may often be wasteful. Polling can also prevent the system from entering low-power mode, and it is best to include a delay in the loop to voluntarily yield the CPU. Otherwise, if this task has the highest priority, it may execute continuously and starve lower-priority tasks.

3. Interrupts

This method uses DMA’s half-transfer interrupt (HT), transfer complete interrupt (TC), and the UART’s IDLE interrupt.

STM32 UART DMA Reception

When one of these three interrupts occurs, data is processed directly within the interrupt.

STM32 UART DMA Reception

This method can handle both sporadic and large amounts of data reception effectively. HT and TC ensure that data is received and processed in a timely manner, preventing data overwriting. Interrupts are triggered only under specific conditions, avoiding frequent disruptions to the main program’s execution, allowing the main program to execute other tasks freely. However, UART processing cannot be executed in the main program, and the interrupt priorities for DMA and USART must be the same to avoid synchronization issues.

4. Interrupts + RTOS

This method is the most recommended. Data processing occurs in the main program task, while interrupts only send messages to notify the task. This ensures timely data processing while significantly reducing the impact of interrupts on the main program.

STM32 UART DMA Reception

STM32 UART DMA Reception

These are several methods for handling UART reception using DMA. In practical use, the size of the buffer should be adjusted according to the actual situation to ensure timely processing without overflow.

References:

https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

Leave a Comment