STM32 gotchas

This is a collection of more or less unexpected or surprising behaviour of STM32 microcontrollers, whether documented or not. What constitutes a gotcha is subjective, and some of the items here are not gotchas at all, just poiting out a feature or idiosyncracy, which may be surprising for some. Also, some of the items are not STM32-specific at all, but apply more broadly to ARM Cortex-M-based mcus, or are related to C or programming generally.

This collection will grow, check back or subscribe to the RSS if you want to follow. Oh yes, no social media, learn how to use real information sources.

Many items are a result of discussion at STM32 forum at community.st.com. I'll try to give relevant links to forum threads where applicable, but they have changed in the past and may do so in the future too, and I won't be able to go and fix all of them.

There's no particular ordering or sorting, it would be hard to find out something half-sane, so just browse through and enjoy.

Legalese: STMicroelectronics registered STM32 as a trademark in various countries, although I don't exactly know what are the ramifications of this, I am not a lawyer. I am not affiliated with ST. In what I write here I may be completely wrong, use below information at your own risk.

Comments are welcome, email them to stm32 at efton dot sk.



  1. Peripheral clock must be enabled in RCC (else registers cannot be written and read as 0)
  2. Timers' clock is 2x APB clock, if APB divider > 1
  3. Advanced timers (TIM1, TIM8, ...), to enable output, need to set TIMx_BDTR.MOE
  4. Debugging is intrusive (e.g. UART/SPI Rx may not work when debugging)
  5. 'F4/'F2 CCM RAM is not good for DMA nor for bit-banding, nor for code
  6. RTC seemingly does not run if only time is read
  7. Interrupt called without reason (late interrupt source clear)
  8. Timer does not work if ARR=0
  9. TIMx->SR &= ~TIM_SR_flag results in lost interrupts (don't RMW or bit-band on status registers)
  10. Strange behaviour after increasing system clock frequency (FLASH latency has to follow system clock)
  11. DAC output does not go rail-to-rail and the output buffer makes it worse
  12. UART parity bit missing as it counts up to data bits
  13. Delay is 1ms longer than required (SW/library, not STM32-specific)
  14. GPIO is not toggling at a rate promised by datasheet
  15. Timer appears to run slower then is set (unrealistically high interrupt rate)
  16. Interrupt does not fire - some troubleshooting hints
  17. Program freezes after enabling an interrupt
  18. ADC readings not as expected because of high signal impedance
  19. Debugger keeps jumping into interrupt when single stepping on 'F746
  20. NDTR problematic when DMA used as Rx FIFO
  21. SPI master NSS unusable
  22. Writing one byte to SPI transmits two bytes (because of data packing)
  23. STM32 hangs in UART interrupt if Rx overrun is not handled
  24. UART Rx stops working (Rx overrun revisited)
  25. STM32 are not microcontrollers, but SoC causing various timing-related issues
  26. Don't use printf() in interrupt or any other lengthy operation
  27. In 'F4, after enabling backup domain access in PWR, wait before accessing RCC_BDCR or BKPSRAM
  28. SPI master does not work as NSS switches it to slave
  29. Processor (and debugger) hangs while debugging OTG USB Host
  30. Only DMA2 can be used to transfer to/from GPIO in 'F4 and 'F2/'F7
  31. Timer - if compare is enabled, setting CCRx > ARR still causes interrupts and DMA and TRGO
  32. SPI generates too many clocks while Rx in Bidir more, and in Rx-only mode
  33. Smaller packages require port remapping for certain functions namely the USB pins PA11 PA12 on 'F042 in TSSOP20
  34. ADC in 'L47x/48x has an extra switch in GPIOx_ASCR
  35. 'F1 don't have the GPIO AF matrix unlike all other STM32 families
  36. Peripherals don't have unique AF number in GPIO matrix they do in 'L1 and mostly do in 'F2/'F4/'F7
  37. GPIO pin input state can still be read, if it's set to Out or AF and EXTI works, too
  38. Analog switch voltage booster (for ADC and other) to be switched on at lower VDD on certain STM32
  39. Software or watchdog reset does not work if NRST is pulled-up hard externally
  40. First TIM period is too short, prescaler does not work - PSC is preloaded; and so is RCR
  41. One TIM period is too long/one PWM pulse is shorter/longer than expected - use preload when needed
  42. First TIM Update ("PeriodElapsed") interrupt fires immediately after configuration when using Cube/SPL
  43. No bit-banding in Cortex-M0/M0+ but not in Cortex-M7 either
  44. Some STM32 models after first programming don't run and need power-on reset (AN2606 pattern6)
  45. Not only frequency but also VOS setting implies FLASH waitstates
  46. Some pins on my Disco/Nucleo/EVAL board don't work as expected
  47. TIMx_CHxN is not inverted if TIMx_CHx is not enabled