STM32 Blue Pill Baremetal Programming

STM32 Blue Pill USART Programming

A guide to transmitting and receiving data from STM32 Blue Pill development board using USART protocol.

Rohit Nimkar
5 min readNov 12, 2022

The interface is externally connected to another device by three pins. Any USART bidirectional communication requires a minimum of two pins: Receive Data In (RX) and Transmit Data Out (TX):

  1. RX: Receive Data Input is the serial data input. Oversampling techniques are used for data recovery by discriminating between valid incoming data and noise.
  2. TX: Transmit Data Output. When the transmitter is disabled, the output pin returns to its IO port configuration. When the transmitter is enabled and nothing is to be transmitted, the TX pin is at a high level. In single-wire and smartcard modes, this IO is used to transmit and receive the data (at the USART level, data are then received on SW_RX).
USART connection diagram
USART1: connection diagram

Transmitter

The transmitter can send data words of either 8 or 9 bits depending on the M-bit status. When the transmit enable bit (TE) is set, the data in the transmit shift register is output on the TX pin and the corresponding clock pulses are output on the CK pin.

During a USART transmission, data shifts out the least significant bit first on the TX pin. In this mode, the USART_DR register consists of a buffer (TDR) between the internal bus and the transmit shift register.

Every character is preceded by a start bit, which is a logic level low for a one-bit period. The character is terminated by a configurable number of stop bits.

Single byte communication

The TXE bit is always by a write to the data register. The TXE bit is set by hardware and indicates:

  • The data has been moved from TDR to the shift register and the data transmission has started.
  • the TDR register is empty.
  • The next data can be written in the USART_DR register without overwriting the previous data.

The flag generates an interrupt if the TXEIE bit is set.

When a transmission is taking place, a write instruction to the USART_DR register stores the data in the TDR register and which is copied into the shift register at the end of the current transmission.

When no transmission is taking place, a write instruction to the USART_DR register places the data directly in the shift register, the data transmission starts, and the TXE bit is immediately set.

Receiver

The USART can receive data words of either 8 or 9 bits depending on the M bit in the USART_CR1 register.

Character reception

  • The RXNE bit is set. It indicates that the content of the shift register is transferred to the RDR. In other words, data has been received and can be read as well as its associated error flags.
  • An interrupt is generated if the RXNEIE bit is set.
  • In single buffer mode, clearing the RXNE bit is performed by software read to the USART_DR register. The RXNE flag can also be cleared by writing a zero to it. The RXNE bit must be cleared before the end of the reception of the next character to avoid an overrun error.

NOTE: The RE bit should not be reset while receiving data. if the RE bit is disabled during the reception, the reception of the current byte will be aborted.

Programmer’s Model

The control flow and flag configuration are explained in the flow chart given below.

control flow diagram for USART
USART: Control flow diagram

USART can be programmed by following the steps given below

Pin Configuration

  • Enable clock source for USART1 and GPIOA port.
  • Configure pin Tx — PA9 as output and Rx — PA10 as input in alternate function configuration.
Initial pin configuration for RX and TX pins

Baud rate calculation

The value for BRR register is set using following formula.

Baud Rate Register configuration

Enable USART baud generation

To start transmitting and receiving data from USART, the following flags in CR1 registers must be set.

  • TE — (Transmitter Enable) This bit enables the transmitter.
  • RE — (Receiver Enable) This bit enables the receiver.
  • RXNEIE — (Receiver Not Empty Interrupt Enable ) Enables the interrupt as the name suggests. This interrupt is triggered when a frame is transferred from the receiver shift register to the receiver data register (RDR).
  • US — (USART Enable) When this bit is cleared the USART pre-scalers and outputs are stopped and the end of the current byte transfer in order to reduce power consumption.

Apart from setting the above flags, interrupt associated with USART1 is enabled from NVIC using CMSIS API.

Transmit data

In order to transmit multi-byte data, one byte at a time is passed to the putc function until NULL ( \0 ) character is encountered.

USART1_puts() function definition

Before writing any data byte to the transmitter data register (TDR), it is recommended to check if the TDR register is empty, else keep waiting till it is empty. TXE bit is set by hardware when the content of the TDR register has been transferred into the shift register. It is cleared by a write to the USART_DR register.

USART_putch() function definition

Receive data

Instead of polling continuously if data is received, receiver interrupt is enabled. Whenever a frame is accepted then it is echoed back to the transmitter. The interrupt service routine handles this task.

Interrupt Service Routine for USART1

Getting the source code

The entire source code for this project along with a detailed guide is available on GitHub.

If you are new to bare-metal programming using visual studio code then the following article will help you get started.

--

--

Rohit Nimkar

Know a little about coding but aim to self employ myself from it.