Working with STM32 and UART part 1: Sending a single Character

UART

In this guide, we shall discuss how to use the UART module on STM32F4xx specifically, STM32F411RE Nucleo.

In this guide we will cover the following:

  • What is UART
  • How to configure the UART on STM32F4xx
  • Code
  • Demo

1. What is UART

To transfer data, computers adopt two method: serial and parallel. In serial communication data is sent a bit at a time (1 line)while in parallel communication 8 or more lines are often used to transfer data. The UART is a form of serial communication. When distance is short, digital signal can be transferred as it is on a single wire and require no modulation. This is how PC keyboard transfer data between the keyboard and motherboard. For long distances like telephone lines, serial data communication requires a modem to modulate.We will not go into the details of this in this lesson, this shall be left for subsequent lessons. 

Synchronous vs. Asynchronous

Serial communication operate in two ways : synchronous and asynchronous. In the synchronous mode, a block of data is sent at a time while in the asynchronous mode, a single byte of data is sent at a time. It is possible to write code to provide both the synchronous and asynchronous serial communication functions however this could turn out tedious and over complicated therefore, special chips are manufactured to perform these functions. When these chips are added to a microcontroller, they become known as Serial Communication Interface (SCI). The chip that provides the the asynchronous communication (UART) is the main theme of this lesson. The chip for synchronous communication is known as the USART and shall left for another lesson. 

Asynchronous Communication Data Framing

The data is received in zeros and ones format, in order to make sense of the data, the sender and the receiver must agree on a set of rules i.e. a protocol, on how data is packed, how many bits constitute a character and when data begins and ends.

The Protocol

  1. Start and Stop bits

Asynchronous serial communication is widely used in character transfer. Each character is packed between start and stop bits. This is known as the framing.

start bit :  Always 1 bit, value is always 0

stop bit:   1 or 2 bits, value is always 1

Lets take an example. Lets say we are transferring ASCII character ‘A’ 

its binary code is 0100 0001 and 0x41 in hex.Furthermore, it is framed between a start bit and 2 stop bits. This is what its frame will look like.

 2. Parity bit

Some systems require parity bit in order to maintain data integrity.The parity bit of a character byte is included in the data frame after the stop bit(s).

 3.Rate of data transfer : Baud rate/bps

We shall explain this concept with an example. Lets say we are asked to calculate the number of bits used  and time taken in transferring 50 pages of text, each with 80×25 characters. Assuming 8 bits per character and 1 stop bit

solution

For each character a total of 10 bits is used ( 1 start bit, 8 bits character, 1 stop bit).

Therefore total number of bits  = 80 x 25 x10 = 20,000 bits per page

50 pages  implies, 50×20,000  =  1,000,000 bits.

Therefore it will take 1 million bits to transfer  this information.

The time it takes to transfer the entire data using

a. 9600 baudrate implies,  1,000,000 / 9600 = 204 seconds

b. 57,600 baudrate implies 1,000,000 /57,600 = 17 seconds

Baudrate simply means the transfer of bits per second. There are various standardized baudrate we can choose from when we program our serial communication devices.  The key thing is, both communication devices must have the same baudrate. We shall see this later on in our example code.

2. How to Configure UART on STM32F4xx

  1. Enable Clock access to UART

First, we need to check which bus is the UART2 connected to

Block diagram

As shown in block diagram, UART2 is connected to APB1, hence we can enable clock access as following

RCC->APB1ENR|=RCC_APB1ENR_USART2EN;

2. Locating which pins are for USART and configure them

According to pinout, USART2 pins are connected to PA2 and PA3

USART Pinout

Hence, we need to enable clock access to GPIOA as following

RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;

Since the UART is a special function, we need to set PA2 as Alternate Function as following

Mode register

Hence we need to set bit5 to 1 and reset bit4 to enable alternate function for PA2

GPIOA->MODER|=(1<<5);//set bit5
GPIOA->MODER&=~(1<<4);//reset bit4

Since we set the pin as alternate function, we need to inform the cpu which type of function to be, in this case we need to know which alternate function is connected to USART2

This information can be found I/O pin multiplexer and mapping section of GPIO in reference manual

Alternate function map

hence, we need to set PA2 to be ALT7 as following

GPIOA->AFR[0]|=0x700;

Thats all for GPIO configuration, now we need to configure the USART module

3. Configure UART

First we need to configure the baudrate which can be calculated as following

baud rate calculation example

Since out MCU is running at 16MHz and we need baud rate of 9600, we need to set the BRR register as following

USART2->BRR=0x0681;

From CR1 we need to set the UART to transmit and enable it

Control register 1 of UART
USART2->CR1  |=0x2008; // enable tx and uart

4. sending a single character

In order to send a single character, we need the following steps:

  • wait to TX buffer to be empty
  • Send the data
while(!(USART2->SR&0x0080)){
}
USART2->DR=(ch);

3. Code:

#include "stm32f4xx.h"                  // Device header

void USART_write(int ch);
void USART2_Init(void);
void delay(int delayms);
int main(){

USART2_Init();
while(1){
USART_write('!');//print !	
USART_write('\r');USART_write('\n'); //new line and return cursor to start of the line
delay(10);
}
}

void USART2_Init(void){
RCC->APB1ENR|=RCC_APB1ENR_USART2EN;
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;
GPIOA->AFR[0]=0x0700;
GPIOA->MODER|=(1<<5);//set bit5
GPIOA->MODER&=~(1<<4);//reset bit4
USART2->BRR  = 0x0681;    //9600 @16MHz
USART2->CR1  |=0x2008; // enable tx

}

void USART_write(int ch){
while(!(USART2->SR&0x0080)){
}
USART2->DR=(ch);
	
}

void delay(int delayms){
int i;
	for(; delayms>0;delayms--){
	for(i=0;i<3192;i++);
	}
}

Result

5 Comments

Add Comment

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