STM32F411 USART2 not working
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.
