STM32 UART Receive Unknown Length (IDLE Line Detection)

In this tutorial, we’ll discuss how to use STM32 UART To Receive Unknown Length Data. Using the STM32 UART IDLE Line Detection hardware feature is one way to achieve the task of receiving unknown length data over UART with STM32 microcontrollers.

We’ll implement two example projects for STM32 UART IDLE Line Detection With Interrupt & DMA to practice what we’ll learn in this tutorial. Without further ado, let’s get right into it!

Table of Contents

  1. STM32 UART Receive Unknown Length Data
  2. STM32 UART IDLE Line Detection
  3. STM32 UART Receive Unknown Length Examples Overview
  4. STM32 UART IDLE Line Detection + Interrupt Example
  5. STM32 UART IDLE Line Detection + DMA Example
  6. Wrap Up

STM32 UART Receive Unknown Length Data

Many communication protocols don’t have predefined message lengths. In such situations, we need to receive an unknown length of data over UART and detect the end of each data stream so the CPU can process the received data stream. Examples include terminal commands, sensor data streams, and custom protocols. In these cases, the receiving device needs to dynamically determine and receive unknown data length.

Several techniques can be implemented to handle receiving unknown length data over UART with STM32 microcontrollers, which include:

  • Time-Out Mechanism: Wait for a predefined period of inactivity to consider the end of the message. This is a very simple, yet effective, technique but can be inefficient and error-prone if the time-out value is not well-tuned.
  • Fixed-Size Buffer + Overrun Detection: Allocate an RX buffer and receive the data byte-by-byte. Implement an overrun check to ensure the buffer doesn’t overflow. This approach is simple but can lose data if messages exceed the buffer size.
  • Delimiter-Based Reception: Use a specific character or sequence of characters to indicate the end of the data. This technique is reliable but requires that the data communication protocol includes such delimiters. So it’s widely used for developing customized communication protocols.
  • Packet Header With Data Length Info: Include a header in the data stream containing the message length. This technique adds some processing overhead but enables flexible data handling.
  • UART IDLE Line Detection: Utilize the STM32’s UART hardware feature to detect periods of inactivity on the receiving line. This is what we’ll use in this tutorial’s examples and will go deeper into in the next section.

STM32 UART IDLE Line Detection

The IDLE line detection feature in STM32’s UART hardware allows the microcontroller to detect a period of inactivity on the UART line. When the line remains idle for one frame duration, an IDLE flag is set in the UART status register. This flag can trigger an interrupt, allowing the software to process the received data.

IDLE line detection is particularly useful for receiving unknown-length data because it provides a clear indication of when the transmission has ended. By using the IDLE flag, the microcontroller can determine that the sender has stopped sending data, allowing the received data to be processed without needing a predefined length or delimiter.

STM32 UART IDLE Line Detection HAL APIs (Functions)

There are 3x HAL APIs (Functions) for UART IDLE Line Detection that can be used for receiving unknown data length with STM32’s UART module. Those functions can be categorized as follows:

  • Blocking: Polling
  • Non-Blocking: Interrupt or DMA

The IDLE Line Detection UART Receive Functions are as follows:

Next up, we’ll implement two example projects for STM32 receiving unknown length data over UART using the IDLE Line Detection feature. First, we’ll do it with interrupt, and in the second example, we’ll do it with DMA. There is no point in doing it using polling as it’ll not be very useful for most of you despite it being doable!


STM32 UART Receive Unknown Length Examples Overview

In the following two example projects, we’ll receive an unknown length of data bytes from the PC terminal and echo back the received data. So in the testing, we’ll expect to see back whatever data we send through the terminal.

The STM32 microcontroller will automatically detect the message reception completion, determine the length of the data received, and send it back to the PC over UART. So we can execute the whole test procedure in the serial monitor.


STM32 UART IDLE Line Detection + Interrupt Example

Step #1

Open STM32CubeMX, create a new project, and select the target microcontroller.

Step #2

Enable UART1 and leave the default configurations as is without a change (9600 baud rate).

STM32 UART Receive DMA Interrupt Polling Example Tutorial

Enable The USART1 Global Interrupt From The NVIC Settings Tab

STM32 UART Receive DMA Interrupt Polling Example Tutorial With Code

Step #3

Go to the RCC clock configuration page and enable the HSE external crystal oscillator input.

STM32 RCC External Clock Selection CubeMX

Step #4

Go to the clock configurations page, and select the HSE as a clock source, PLL output, and type in 72MHz for the desired output system frequency. Hit the “ Enter” key, and let the application solve for the required PLL dividers/multipliers to achieve the desired clock rate.

STM32-Blue-Pill-Proteus-Library-Simulation-Clock-Configuration

Step #5

Name & Generate The Project Initialization Code For CubeIDE or The IDE You’re Using.

STM32 UART IDLE Line Detection Interrupt Example Code

Here is The Application Code For This LAB (main.c)

Code Explanation

In the main() function, we Call the HAL_UARTEx_ReceiveToIdle_IT() to start the reception of UART data in the UART1_RxBuffer using IDLE line detection in interrupt mode.

The Rx interrupt is fired and the ISR function HAL_UARTEx_RxEventCallback() is called whenever the hardware detects an IDLE event or we’ve already received the maximum buffer length of data UART_RX_BUFFER_SIZE. In the ISR Callback function:

  • Save the received data length (size) into the RxDataLen variable
  • Echo back the received data over UART to the PC using the HAL_UART_Transmit() function
  • Re-start the UART data reception with IDLE line detection in interrupt mode again, and so on…

STM32 UART Receive Unknown Length Example Testing

This is the testing result on the serial monitor showing the echo message which is exactly what we’ve sent to the STM32 microcontroller. The message I’ve sent from the PC to the STM32 microcontroller has been received in the UART1_RxBuffer array as you can see in the live expressions window of the debugger.

Pay attention to the line where I’ve placed the breakpoint as you’ll need to add this breakpoint to perform the same testing as shown below. Also, note that the received message length is correctly detected and stored in the RxDataLen variable.

STM32-UART-Receive-Unknown-Data-Length-IDLE-Line-Detection-Interrupt-Example


STM32 UART IDLE Line Detection + DMA Example

This second example project is exactly the same as the previous one. However, in this example, the transfer of the received UART data to the global array variable will be handled through the DMA unit instead of the CPU.

Step #1

Open STM32CubeMX, create a new project, and select the target microcontroller.

Step #2

Enable UART1 and leave the default configurations as is without a change (9600 baud rate).

STM32 UART Receive DMA Interrupt Polling Example Tutorial

Enable The USART1 Global Interrupt From The NVIC Settings Tab

Add A DMA Channel For UART RX From The DMA Tab With The Following Settings

STM32-UART-Receive-Unknown-Data-Length-IDLE-Line-Detection-DMA-Example-CubeMX

Step #3

Go to the RCC clock configuration page and enable the HSE external crystal oscillator input.

STM32 RCC External Clock Selection CubeMX

Step #4

Go to the clock configurations page, and select the HSE as a clock source, PLL output, and type in 72MHz for the desired output system frequency. Hit the “ Enter” key, and let the application solve for the required PLL dividers/multipliers to achieve the desired clock rate.

STM32-Blue-Pill-Proteus-Library-Simulation-Clock-Configuration

Step #5

Name & Generate The Project Initialization Code For CubeIDE or The IDE You’re Using.

STM32 UART IDLE Line Detection DMA Example Code

Here is The Application Code For This LAB (main.c)

Code Explanation

In the main() function, we Call the HAL_UARTEx_ReceiveToIdle_DMA() to start the reception of UART data in the UART1_RxBuffer using IDLE line detection in DMA mode.

The Rx interrupt is fired and the ISR function HAL_UARTEx_RxEventCallback() is called whenever the hardware detects an IDLE event or we’ve already received the maximum buffer length of data UART_RX_BUFFER_SIZE. In the ISR Callback function:

  • Save the received data length (size) into the RxDataLen variable
  • Echo back the received data over UART to the PC using the HAL_UART_Transmit() function
  • Re-start the UART data reception with IDLE line detection in DMA mode again, and so on…

STM32 UART Receive Unknown Length Example Testing

This is the testing result on the serial monitor showing the echo message which is exactly what we’ve sent to the STM32 microcontroller. The message I’ve sent from the PC to the STM32 microcontroller has been received in the UART1_RxBuffer array as you can see in the live expressions window of the debugger.

Pay attention to the line where I’ve placed the breakpoint as you’ll need to add this breakpoint to perform the same testing as shown below. Also, note that the received message length is correctly detected and stored in the RxDataLen variable.

STM32-UART-Receive-Unknown-Data-Length-IDLE-Line-Detection-DMA-Example

❕ Note

Note That in this example we don’t wait for the DMA transfer completion because we want to capture the end of the incoming data stream and process the received message. The DMA here is only used for data transfer byte-by-byte from the UART Rx buffer register to the UART1_RxBuffer array.


Required Parts For STM32 Examples

All the example Code/LABs/Projects in this STM32 Series of Tutorials are done using the Dev boards & Electronic Parts Below:

QTY.Component NameAmazon.comAliExpresseBay
1STM32-F103 BluePill Board (ARM Cortex-M3 @ 72MHz)AmazonAliExpresseBay
1Nucleo-L432KC (ARM Cortex-M4 @ 80MHz)AmazonAliExpresseBay
1ST-Link V2 DebuggerAmazonAliExpresseBay
2BreadBoardAmazonAliExpresseBay
1LEDs KitAmazonAmazonAliExpresseBay
1Resistors KitAmazonAmazonAliExpresseBay
1Capacitors KitAmazonAmazonAliExpress & AliExpresseBay & eBay
1Jumper Wires PackAmazonAmazonAliExpress & AliExpresseBay & eBay
1Push ButtonsAmazonAmazonAliExpresseBay
1PotentiometersAmazonAliExpresseBay
1Micro USB CableAmazonAliExpresseBay

★ Check The Links Below For The Full Course Kit List & LAB Test Equipment Required For Debugging ★

Download Attachments

You can download all attachment files for this Article/Tutorial (project files, schematics, code, etc..) using the link below. Please consider supporting our work through the various support options listed in the link down below. Every small donation helps to keep this website up and running and ultimately supports the whole community.


Wrap Up

In conclusion, we’ve explored how to set up the STM32 UART to receive unknown data length using IDLE line detection both in interrupt mode & DMA mode. You can build on top of the examples provided in this tutorial and/or explore the other parts of this STM32 UART tutorial series linked below.

This Tutorial is Part of The Following Multi-Part Tutorial Series:
(6) UART Receive Unknown Length (IDLE Line Detection)
STM32-UART-Receive-Unknown-Length-IDLE-Line-Detection
(7) UART Single-Wire (Half-Duplex) Tutorial & Examples
STM32-UART-Single-Wire-Half-Duplex-Tutorial-Examples
(8) STM32 UART Multi-Processor Communication
STM32-UART-Multiprocessor-Communication

Share This Page With Your Network!
Join Our +25,000 Newsletter Subscribers!

Stay Updated With All New Content Releases. You Also Get Occasional FREE Coupon Codes For Courses & Other Stuff!

Photo of author
Author
Khaled Magdy
Embedded systems engineer with several years of experience in embedded software and hardware design. I work as an embedded SW engineer in the Automotive & e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI/ML, and other fields I'm passionate about.
I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?

Leave a Comment