cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F411 USART2 not working

teosssss
Associate II

Hello,

I am having trouble getting USART2 to work on my custom STM32F411 discovery board. I have written initialization code for USART2 but I am not seeing any output in my terminal program (minicom).

Here are the key parts of my code:

void usart_init(USART_TypeDef* usart)
{
  /* Enable USART2 clock */
  RCC->APB1ENR |= (1 << RCC_APB1ENR_USART2EN_Pos);

  /* Enable GPIOA clock*/
  RCC->AHB1ENR |= (1 << RCC_AHB1ENR_GPIOAEN);

  /* Set PA2 and PA3 to alternate function */
  GPIOA->MODER &= ~(GPIO_MODER_MODE2_Msk | GPIO_MODER_MODE3_Msk);
  GPIOA->MODER |= (0b10 << GPIO_MODER_MODE2_Pos) | (0b10 << GPIO_MODER_MODE3_Pos);

  /* Configure USART2 to use AF7 on PA2, PA3 */
  GPIOA->AFR[0] &= ~(GPIO_AFRL_AFRL2 | GPIO_AFRL_AFRL3);
  GPIOA->AFR[0] |= (7 << GPIO_AFRL_AFSEL2_Pos) | (7 << GPIO_AFRL_AFSEL3_Pos);

  /* Configure 9600 baud @ 16 MHz PCLK */
  set_baud_rate(USART2, 16000000, 9600);

  USART2->CR1 |= USART_CR1_UE | USART_CR1_TE; // USART enable and transmitter enable

  while (!(USART2->SR & USART_SR_TC));
}

int main(void)
{
  usart_init(USART2);

  while (1) {
    usart_write(USART2, "c");
    delay_ms(1000);
  }
}

void usart_write(USART_TypeDef* usart, char c)
{
  // put data in data register
  usart->DR = c;
  // loop till status register bit 7 is set
  // status register bit 7 is 1 when transmission is completed
  while (!(usart->SR & USART_SR_TC));
}

void set_baud_rate(USART_TypeDef* USARTx, uint32_t PCLK, uint32_t Baudrate)
{
  // Calculate the USARTDIV value
  float USARTDIV = (float)PCLK / (Baudrate * 16.0f);
  // Calculate the Mantissa part
  uint16_t Mantissa = (uint16_t)USARTDIV;
  // Calculate the Fraction part
  uint16_t Fraction = (uint16_t)((USARTDIV - Mantissa) * 16);
  // Combine the Mantissa and Fraction and write to the BRR register
  USARTx->BRR = (Mantissa << 4) | (Fraction & 0x0F);
}
```

I have verified:

- The clock is the default HSI clock, so 16MHz.

- APB1 bus should be 16Mhz
- USART2 clock is enabled
- GPIOA clock is enabled
- PA2 and PA3 are set to alternate function mode
- PA2 and PA3 are configured to use AF7 for USART2
- Baud rate is set to 9600 for 16 MHz peripheral clock
- USART2 is enabled and transmitter is enabled

I am able to see debug prints in terminal using STM32CubeIDE HAL, so I know the core is running. But I get no output if i set up USART2 manually .

Does anything look incorrect in my USART2 initialization? Are there any other USART2 settings I should check?

My terminal program is configured for 9600 baud, 8 data bits, no parity, 1 stop bit which I believe matches the USART2 configuration.


I have also tried different baud rates but the error still occurs.

I think the problem is something related to the baud rate but i cannot find it right now.

Also LED blinking inside the main loop works, so it does not get stuck somewhere in the code.

Any suggestions to help troubleshoot this would be greatly appreciated! Let me know if you need any other details about my setup.

1 ACCEPTED SOLUTION

Accepted Solutions
teosssss
Associate II

The problem was that I was not enabling GPIOA clock, but GPIOB clock because
RCC->AHB1ENR |= (1 << RCC_AHB1ENR_GPIOAEN) was shifting by 1;
so instead i have just put RCC->AHB1ENR |= (1 << RCC_AHB1ENR_GPIOAEN_Pos)

View solution in original post

4 REPLIES 4
SMSAD.1
ST Employee

Hello teosssss,

Did you verify with the Device Manager that you are connected to the correct COM port and also that his port settings are the same as yours?

To check the COM port and settings, follow these steps:

  1. Open Device Manager.
  2. Expand the Ports (COM & LPT) section.
  3. Look for your device and note the COM port number.
  4. Right-click on the device and select Properties.
  5. Go to the Port Settings tab to view and match the settings.

 

 

Hello,

Thank you for your suggestion. I have already verified that my device is connected to the correct port and that the settings match between the device and the terminal.

I checked that my device is connected to /dev/ttyUSB0 .

Furthermore, I have configured minicom to use the correct settings for my device:

```
| 9600 8N1 | NOR | Minicom 2.8 | VT102 | Offline | ttyUSB0
```

This shows that minicom is set to:
- 9600 baud rate
- 8 data bits
- No parity
- 1 stop bit
- Hardware flow control: No
- Terminal type: VT102
- Serial port: ttyUSB0

To double-check that the communication is working correctly, I flashed a firmware created using STM32CubeIDE to my device. The firmware was configured to send output to the serial port. I was able to see the expected output in the minicom terminal, confirming that the serial communication between the device and the computer is functioning properly.

i have also tried to brute force all the possible uint16_t values inside the USART->BRR register but still no output.


At this point I'am lost and i really don't have any idea where the error could be

Thank you for your reply.

SMSAD.1
ST Employee

 

- Can you test your board with an existing example from the STM32Cube_FW_F4

- try change to another terminal like Hercules

teosssss
Associate II

The problem was that I was not enabling GPIOA clock, but GPIOB clock because
RCC->AHB1ENR |= (1 << RCC_AHB1ENR_GPIOAEN) was shifting by 1;
so instead i have just put RCC->AHB1ENR |= (1 << RCC_AHB1ENR_GPIOAEN_Pos)