Building Board Support Package (BSP) for STM32F411-Nucleo64 Part6: UART in TX-RX Mode

In the previous guide, we took a look at building BSP for UART in TX mode. Now, we shall develop the BSP for UART receiver and use UART2 in full duplex mode.

In this guide, we shall cover the following:

  • Develop the header file.
  • Develop the source file.
  • Main.c
  • Code.
  • Results.

1. Develop the header file.

From the previous guide, open uart_bsp.h file and declare the following function:

UART_StatusTypedef BSP_UART_Read_Char(USART_TypeDef *uart,char *recChar, uint32_t timeout);

The function will take three arguments:

  • Pointer USART_Typedef to handle which UART to be used.
  • Pointer to hold the data to be read.
  • timeout to handle the time in the firmware.
  • Return UART_StatusTypedef.

Thats all for the header file.

2. Develop the source file.

Open uart_bsp.c source file.

Include the function:

UART_StatusTypedef BSP_UART_Read_Char(USART_TypeDef *uart,char *recChar, uint32_t timeout)

In order to read a single character, the following steps are required:

  • Wait until the receiver buffer is filled.
  • Read the data register.

Within the function:

Get the current tick and store it to indicate the start of the time:

uint32_t start_ticks= BSP_Get_Ticks();

Wait until the buffer is filled using while loop:

while(!(uart->SR & USART_SR_RXNE))

Since we don’t want to get stuck here forever, we shall check for timeout, if timeout occurred, we shall return timeout as following:

/*Time out management*/
if(BSP_Get_Ticks()-start_ticks>timeout)
{	/*Return if timedout, return timeout*/
	return UART_TIMEOUT;
}

If the character is received before timeout, get the new data and store in the pointe as following:

/*Read data*/
*recChar= uart->DR;

Return success:

return UART_SUCCESS;

Hence the entire function as following:

UART_StatusTypedef BSP_UART_Read_Char(USART_TypeDef *uart,char *recChar, uint32_t timeout)
{
	uint32_t start_ticks= BSP_Get_Ticks();

	  /*Make sure the receive data register is not empty*/
		while(!(uart->SR & USART_SR_RXNE))
		{
			/*Time out management*/
			if(BSP_Get_Ticks()-start_ticks>timeout)
			{	/*Return if timedout, return timeout*/
				return UART_TIMEOUT;
			}
		}

		/*Read data*/
		*recChar= uart->DR;

		return UART_SUCCESS;

}

3. Main.c:

In main.c :

#include "bsp.h"
#include "uart_bsp.h"
void clock_config(void);

char uart_char;



int main()
{

	clock_config();

	GPIOA_CLOCK_ENABLE();

	GPIO_Configure_Typedef PA2_ALT;

	PA2_ALT.PinNumber=pin2;
	PA2_ALT.Mode=Alternate_function;
	PA2_ALT.AlternateType=AF7;
	GPIO_Initialization(GPIOA,&PA2_ALT);


	GPIO_Configure_Typedef PA3_ALT;

	PA3_ALT.PinNumber=pin3;
	PA3_ALT.Mode=Alternate_function;
	PA3_ALT.AlternateType=AF7;
	GPIO_Initialization(GPIOA,&PA3_ALT);



	UART2_CLOCK_ENABLE();

	UART_ConfigTypedef uart_config;

	uart_config.buadRate=115200;
	uart_config.busSpeed=50000000;
	uart_config.mode=UART_TX_RX;

	BSP_UART_Init(USART2, &uart_config);

	BSP_Ticks_Init(100000000);


	while(1)
	{

		if (BSP_UART_Read_Char(USART2, &uart_char, 100)==UART_SUCCESS)
		{
		BSP_UART_Write_Char(USART2,uart_char,100);
		BSP_UART_Write_Char(USART2,'\r',100);
		BSP_UART_Write_Char(USART2,'\n',100);
		}

	}

}

void clock_config(void)
{
	Clock_Config_Typedef clockConfig;

	clockConfig.PLL_M= 4;
	clockConfig.PLL_N= 200;
	clockConfig.PLL_P= 4;

	clockConfig.AHB1Prescaler=AHB1_Prescaler1;
	clockConfig.APB1Prescaler=APB1_Prescaler2;
	clockConfig.APB2Prescaler=APB2_Prescaler1;

	clockConfig.clockSourc=External_Oscillator;
	clockConfig.flash_latency= Three_wait_state;

	Clock_Configuration(&clockConfig);
}

4. Code:

You may download the code from here:

5. Results:

Open your serial terminal, set the baud rate to 115200 and send any character you will get the send character back:

Happy coding 🙂

Add Comment

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