cancel
Showing results for 
Search instead for 
Did you mean: 

USART error in STM32F4

Yoshimitsu_Manji_clan
Associate II

Good evening community members,

today I have been trying to activate USART module of my STM32F446 board. However even after trying everything, I could not sense Tx signal on PA2 pin of the board. This is the low level code I used. I had been trying to capture the signal using Oscilloscope but got nothing. Could someone help me how to resolve the issue? I tried my best but found nothing so far. Thanks in advance. 

 

#include "stm32f4xx.h"
#include <stdint.h>
#include <stdio.h>

void gpio_init(void)
{

	RCC->APB1ENR  |=   (1U<<17);     //enable clock for USART2
	GPIOA->MODER  |=   (0b10<<4);    //setting PA2 in alternate function mode
	GPIOA->AFR[0] |=   (0b0111<<8);  //setting PA2 in AF7 mode
	RCC->AHB1ENR  |=   (1U<<0);      //enable GPIO Port A
}

void usart_init(void)
{
	USART2->BRR   =   (0x8B);      //setting baud rate as 115200
	USART2->CR1   =   (1U<<3);     //transmitter enable
	USART2->CR1   |=   (1U<<13);    //enable USART
}

void usart2_data(char c)
{
	while (!(USART2->SR & (1U<<7))){}
	USART2->DR = c;
}

#include <usart_tx.h>


int main(void)
{
	gpio_init();
	usart_init();
	while (1)
	{
		usart2_data('Y');
	}
}

 

11 REPLIES 11
Imen.D
ST Employee

Hello @Yoshimitsu_Manji_clan,

Ensure that UART settings (stop bits, word length, parity, baud rate...) are configured correctly.

Check if there is no other peripherals are interfering with PA2.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

Recheck your baud rate calculation.

Baudrate calculations are as follows:

USARTDIV = (16 * 1000000)/(115200 * 16) =  8.68

Mantissa = 8

Fraction = 0.68 * 16 = 10.88 ~~ 11

Hence BRR = 0x8B

GPIOA->MODER  |=   (0b10<<4);    //setting PA2 in alternate function mode
	GPIOA->AFR[0] |=   (0b0111<<8);  //setting PA2 in AF7 mode
	RCC->AHB1ENR  |=   (1U<<0);      //enable GPIO Port A

You have to set RCC_AHB1ENR.GPIOAEN *before* accessing the GPIOA registers.

You may also want to do that so that there is a delay between setting the clock enable in RCC and first accessing the given peripheral; see errata.

At any case, when in doubts, start debugging with reading out and checking content of the relevant registers.

JW

 

The proper formula for BRR is

USART2->BRR = (USART_CLK_FREQ + BAUD_RATE / 2) / BAUD_RATE;

which yields the value of 139 decimal - the same as in you code by a wild chance.

Also, UART CR1 register should be set to:

USART2->CR1 = USART_CR1_TE | USART_CR1_UE;

- it will not work with TE bit clear.

The main problem with you code is what @waclawek.jan wrote - GPIOA not enabled during config.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

In my code I have set TE bit as 1

USART2->CR1   =    (1U<<3);     //transmitter enable

Also I have enabled GPIOA before configuring its Alternate Function. 

RCC->APB1ENR  |=   (1U<<17);     //enable clock for USART2
RCC->AHB1ENR  |=   (1U<<0);      //enable GPIO Port A
GPIOA->MODER  |=   (0b10<<4);    //setting PA2 in alternate function mode
GPIOA->AFR[0] |=   (0b0111<<8);  //setting PA2 in AF7 mode

still I can't see data pulses at PA2 pin. This pin is not configured for any other purpose in this program. 

Anything else I need to check to make it work?  

Read out and check/post content of UART and relevant GPIO registers.

Make sure the hardware is OK by setting PA2 to GPIO Out and toggling it either manually in debugger, or in program using a simple loopdelay (as in the basic blinky).

JW

I meant UE bit, as shown in my code fragment above.

Your code would be a lot easier to read and debug if you used standard bit names instead of cryptic magic expressions.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

I took the above code with the correction for GPIO clock enable, commenting out #include <usart_tx.h> which I don't have, and in a DiscoF4 it works as expected, transmitting infinitely on PA2, as observed by oscilloscope.

Now if you observe this using a UART receiver (e.g. UART-USB converter, fed into a PC), depending on how it is started, it may get confused by the infinite stream with no spaces if it does not get synchronized properly on the first character. Try to place delays between the characters.

JW