What I was trying to do
Send “hello” over UART2 on an STM32F4 Discovery, no HAL, registers only.
What went wrong
Nothing on the serial monitor. Code compiled and ran fine.
How I debugged it
Logic analyzer on PA2 — the line was flat. So the pin was never actually driven by the UART peripheral.
The bug
I enabled the USART2 clock but forgot the GPIOA clock, and never set the alternate function. The pin stayed a plain input.
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // this line was missing
GPIOA->MODER |= (2 << (2 * 2)); // PA2 -> alternate function
GPIOA->AFR[0] |= (7 << (4 * 2)); // AF7 = USART2
What I learned
On STM32, a peripheral needs two clocks enabled: the peripheral’s own and the GPIO port’s. Reading the datasheet’s clock tree earlier would have saved me two hours.