STM32 UART Half-Duplex (Single Wire) Tutorial & Examples

In this tutorial, we’ll discuss how the STM32 UART Half-Duplex (Single Wire) mode works. You’ll learn how to use the STM32 UART half-duplex mode to send and receive data over UART with a single wire.

We’ll implement an example project for STM32 UART Half-Duplex Transmitter/Receiver to practice what we’ll learn in this tutorial by creating two-way communication between two STM32 board over UART in half-duplex mode. Without further ado, let’s get right into it!

Table of Contents

  1. STM32 UART Half-Duplex (Single Wire) Mode
  2. How To Send Data With STM32 UART Half-Duplex
  3. How To Receive Data With STM32 UART Half-Duplex
  4. STM32 UART Half-Duplex Example Overview
  5. STM32 UART Half-Duplex (Single Wire) Example
  6. Wrap Up

STM32 UART Half-Duplex (Single Wire) Mode

The STM32 UART can be configured to operate in half-duplex mode (single wire). In this mode, the UART module can send or receive data using only one wire (line) but not at the same time. It keeps switching between transmitter mode and receiver mode in runtime to achieve this behavior.

In single-wire half-duplex mode, the TX and RX pins are connected internally. The RX pin is no longer used. The TX pin is always released when no data is transmitted. Thus, it acts as a standard IO in idle or in reception. This means that the IO must be configured so that TX pin is in alternate-function open-drain mode with an external pull-up resistor.

The STM32 UART hardware may or may not have this pull-up internally. This should be mentioned in the datasheet of the exact STM32 microcontroller. For the demo example I’ve created and tested on my hardware, it was necessary to hook up an external pull-up resistor to get it working reliably. A 4.7kΩ resistor to Vcc should be fine for most situations.


How To Send Data With STM32 UART Half-Duplex

To send data in half-duplex mode with STM32 UART, you need first to enable TX using the HAL_HalfDuplex_EnableTransmitter() function. Then, you can send the data you want to send over UART in half-duplex mode, and switch back to the RX (receiver) mode to capture any incoming data.

Here is an example code for how this is done using STM32 HAL APIs:


How To Receive Data With STM32 UART Half-Duplex

To receive data in half-duplex mode with STM32 UART, you need first to enable RX using the HAL_HalfDuplex_EnableReceiver() function. Then, you can receive data over UART in half-duplex mode. It’s better to use the IDLE Line Detection Receiving scheme to read any unknown number of incoming data bytes and make sure to have the UART interrupt enabled in the NVIC settings.

Here is an example code for how this is done using STM32 HAL APIs:


STM32 UART Half-Duplex Example Overview

In the following example project, we’ll design a two-way communication system between two STM32 microcontrollers using the UART half-duplex single-wire mode.

In this system, each STM32 microcontroller will do the following functions:

  • Read 2x potentiometers (12-Bit values scaled up to 16-bits)
  • (every 5ms) Switch the UART to TX mode, send 4-Bytes of data containing the ADC readings of the 2 potentiometers, and switch back to RX mode
  • When UART data is received with an IDLE line detection event, process the received 4-Bytes of data, and use it to control 2x output PWM LEDs
  • Keep repeating

In other words, each one of the two STM32 microcontrollers will read its own two potentiometers and send the values to control the other STM32’s output LEDs brightness (PWM) over the half-duplex UART bus. Each microcontroller is sending and receiving data “apparently” at the same time in this system.

Here is the connection diagram for this example project.

STM32-UART-Half-Duplex-Example-Wiring


STM32 UART Half-Duplex (Single Wire) Example

Step #1

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

Step #2

Enable UART1 in Single-Wire (Half-Duplex) mode and leave the default configurations as is.

STM32-Single-Wire-Half-Duplex-Mode-Example-Configuration

Enable The USART1 Global Interrupt From The NVIC Settings Tab

STM32 UART Receive DMA Interrupt Polling Example Tutorial With Code

Step #3

Enable the ADC channels: CH8 & CH9

STM32-Single-Wire-Half-Duplex-Example-ADC-Configuration

Step #4

Configure Timer3 to generate 2x PWM outputs on CH1 & CH2 with default configurations as shown below.

STM32-Single-Wire-Half-Duplex-Example-PWM-Configuration

Step #5

Configure Timer2 to generate an interrupt every 5ms using the configurations shown below. I’ve used this STM32 Timer Calculator to get these values.

Step #6

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

STM32 RCC External Clock Selection CubeMX

Step #7

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 #8

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

STM32 UART Half-Duplex Tx/Rx 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.

In the while(1) super loop, we keep sampling the 2x ADC channels to get the potentiometers readings using This ADC Multi-Channel Sampling Technique and store the results in this AD_RES[] buffer array.

Every 5ms, a Timer2 interrupt is fired and the CPU starts executing the HAL_TIM_PeriodElapsedCallback() ISR handler function. In which it does the following:

  • Pack the ADC readings into the UART1_TxBuffer array.
  • Switch the UART mode from receiver to transmitter
  • Transmit the UART1_TxBuffer data
  • Switch back to UART receiver 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
  • Process the received data (ADC readings) and reconstruct the original value of each reading
  • Update the PWM output duty cycle according to the received ADC readings
  • Re-start the UART data reception with IDLE line detection in interrupt mode again, and so on…

STM32 UART Single Wire Tx/Rx Example Testing

This is the testing result for this example project on my two STM32 blue pill boards (F103C6T6). Note how each board’s potentiometers control the other’s LEDs brightness which verifies that the two-way communication is properly established.


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 in Half-Duplex mode to transmit and receive data on the same line (wire) and we’ve established a 2-way communication between 2 STM32 boards using UART half-duplex mode. You can build on top of the example 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:

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