Getting Started with STM32F103: UART Receiver mode

In the previous guide (here), we took a look how to configure the UART to transmit single character. In this guide, we shall use UART to receive a character and echo the received character.

In this guide, we shall cover the following:

  • Configure the pin to work in UART mode.
  • Configure the UART in receiver mode.
  • Receive a character.
  • Code.
  • Demo.

1. Configure the pin to work in UART mode:

From the previous guide, we concluded that PA2 is for TX and PA3 is for RX. Hence, we shall configure PA3.

For the pin to work in UART RX mode, we need to configure it as input floating as following:

/*Set mode to be input*/
	GPIOA->CRL &=~(GPIO_CRL_MODE3);
	GPIOA->CRL|=GPIO_CRL_CNF3_0;
	GPIOA->CRL&=~GPIO_CRL_CNF3_1;

Thats all for the GPIO configuration.

2. Configure UART in Receiver mode:

In order to configure the UART to work in receiver mode, we need to enable the receiver bit in CR1 (Control Register 1):

	//Enable receiver
	USART2->CR1 |= USART_CR1_RE;

3. Receive a character:

In order to receive a character, we need to wait for the character to arrive by checking the status register and the bit Read data register not empty and then read the data register:

char uart2_read(void)
{
	  /*Make sure the receive data register is not empty*/
	while(!(USART2->SR & USART_SR_RXNE)){}

	/*Read data*/
	return USART2->DR;

}

4. Code:

The entire code for both Tx and Rx as follows:

#include "stm32f1xx.h"



#define Perpher_CLK 8000000
#define Baudrate	115200



static uint16_t compute_uart_bd(uint32_t PeriphClk, uint32_t BaudRate)
{
	return ((PeriphClk + (BaudRate/2U))/BaudRate);
}


static void uart_set_baudrate(USART_TypeDef *USARTx, uint32_t PeriphClk,  uint32_t BaudRate)
{
	USARTx->BRR =  compute_uart_bd(PeriphClk,BaudRate);
}





void uart2_write(int ch)
{
  /*Make sure the transmit data register is empty*/
	while(!(USART2->SR & USART_SR_TXE)){}

  /*Write to transmit data register*/
	USART2->DR	=  (ch & 0xFF);
}



char uart2_read(void)
{
	  /*Make sure the receive data register is not empty*/
	while(!(USART2->SR & USART_SR_RXNE)){}

	/*Read data*/
	return USART2->DR;

}



int main(void)
{

	/*UART2 Pin configures*/

	//enable clock access to GPIOA
	RCC->APB2ENR|=RCC_APB2ENR_IOPAEN;
	//Enable clock access to alternate function
	RCC->APB2ENR|=RCC_APB2ENR_AFIOEN;

	/*Confgiure PA2 as output maximum speed to 50MHz
	 * and alternate output push-pull mode*/
	GPIOA->CRL|=GPIO_CRL_MODE2;

	GPIOA->CRL|=GPIO_CRL_CNF2_1;
	GPIOA->CRL&=~GPIO_CRL_CNF2_0;


	/*Configure PA3 as Input floating*/

	/*Set mode to be input*/
	GPIOA->CRL &=~(GPIO_CRL_MODE3);
	GPIOA->CRL|=GPIO_CRL_CNF3_0;
	GPIOA->CRL&=~GPIO_CRL_CNF3_1;




	/*Don't remap the pins*/
	AFIO->MAPR&=~AFIO_MAPR_USART2_REMAP;


	/*USART2 configuration*/

	//enable clock access to USART2

	RCC->APB1ENR|=RCC_APB1ENR_USART2EN;

	//Transmit Enable
	USART2->CR1 |= USART_CR1_TE;

	//Enable receiver
	USART2->CR1 |= USART_CR1_RE;

	/*Set baudrate */
	uart_set_baudrate(USART2,Perpher_CLK,Baudrate);
	//Enable UART
	USART2->CR1 |= USART_CR1_UE;



	while(1)
	{
		char c;
		c=uart2_read();
		uart2_write(c);
		uart2_write('\r');
		uart2_write('\n');


	}
}

5. Results:

Open you favourite serial terminal and set the buadrate to be 115200 and send any character and you should receive the same sent character:

Happy coding 🙂

6 Comments

Add Comment

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