STM32
STMicroelectronics STM32 microcontroller peripherals, toolchains, and design questions.
STM32 is STMicroelectronics' family of ARM Cortex-M microcontrollers, ranging from the entry-level Cortex-M0+ based STM32F0 to the high-performance Cortex-M7 and Cortex-M33 based STM32H7 and STM32U5 series. STM32 is one of the most widely used MCU families in professional embedded product development, valued for its broad peripheral set, mature toolchain, and extensive documentation.
What Is STM32?
STM32 microcontrollers share a common hardware ecosystem:
- ARM Cortex-M core — the processor core, ranging from M0+ (low power, simple) through M4 (FPU, DSP instructions) to M7 and M33 (high performance, TrustZone).
- Peripheral set — GPIO, timers, SPI, I2C, UART/USART, I2S, CAN, USB, ADC, DAC, DMA, and in higher-end parts, Ethernet, camera, display, and cryptography.
- Clock tree — a configurable network of oscillators, PLLs, and prescalers that supply clock signals to each peripheral independently.
- STM32CubeMX — ST's graphical configuration tool that generates initialisation code for peripherals, clocks, and middleware.
- HAL (Hardware Abstraction Layer) — ST's firmware library that provides portable peripheral drivers across STM32 families.
This subtopic is part of the Embedded Systems topic, which covers the broader embedded systems discipline.
Why STM32?
STM32 is a strong choice for commercial product development because:
- Family breadth — from the 32 MHz Cortex-M0+ STM32G0 at under $0.50 (volume pricing) to the 550 MHz Cortex-M7 STM32H7 with 1 MB SRAM, the family covers the full product performance spectrum within one toolchain.
- Long-term availability — STMicroelectronics commits to 10-year production longevity for most STM32 series, reducing redesign risk.
- Toolchain — STM32CubeIDE (Eclipse-based, free), STM32CubeMX (graphical peripheral configuration, code generation), and compatibility with GCC, Keil, and IAR.
- Debug interface — SWD (Serial Wire Debug) and JTAG on all parts; ST-Link V3 is inexpensive and well-supported.
- Ecosystem — extensive documentation, application notes, and community resources (RM0 reference manuals are comprehensive and accurate).
Key Concepts
- Reference Manual (RMxxxx) — the definitive per-series register-level documentation. The RM for the specific STM32 series in use is the authoritative source for peripheral configuration, not just the HAL.
- CubeMX pinout and clock configuration — CubeMX generates a valid clock tree and peripheral configuration, but the engineer must understand the clock tree to set it correctly (PLL source, prescalers, peripheral bus clocks).
- DMA (Direct Memory Access) — transfers data between peripherals and memory without CPU involvement. Essential for efficient high-speed ADC, SPI, and UART transfers. On STM32H7, DMA buffers must reside in DMA-accessible SRAM (not DTCM) — a common footgun when porting from STM32F4; see STM32H7 DMA TEIF: DTCM buffer causing transfer error.
- NVIC (Nested Vectored Interrupt Controller) — the ARM interrupt controller on Cortex-M. Every interrupt has a priority level; correct priority assignment is required for preemptive interrupt handling to work correctly.
- BOOT0 pin — STM32's hardware boot mode selector. BOOT0 high at reset causes the MCU to boot from system memory (where the built-in DFU bootloader lives) rather than from user flash.
- System memory bootloader — the factory-programmed bootloader in STM32's system memory supports USB DFU, UART, SPI, I2C, and CAN firmware loading without any custom bootloader required.
Common Tools and Software
- STM32CubeIDE — ST's free, Eclipse-based IDE integrating the GNU Arm Embedded Toolchain, STM32CubeMX, and a GDB debug front end with ST-Link support. The recommended IDE for new STM32 projects.
- STM32CubeMX — ST's graphical peripheral and clock tree configuration tool. Generates
MX_xxx_Init()initialisation code for all configured peripherals, reducing peripheral setup errors. Integrated into STM32CubeIDE or available as a standalone application. - STM32CubeProgrammer — ST's flashing and option bytes tool for STM32, available as a GUI and CLI. Used for production flashing, DFU bootloader interaction, and reading/writing flash.
- Debug probes — ST-Link V3 (built into every Nucleo and Discovery board, can be used to program/debug external targets), J-Link (SEGGER, faster and better RTT support, preferred for commercial development).
- Reference manuals — the STM32 Reference Manual (RMxxxx, available from st.com for each series) is the definitive register-level documentation. HAL functions ultimately call these registers; the RM is required reading when HAL functions behave unexpectedly.
Common Mistakes
- Not verifying the peripheral clock is enabled — CubeMX enables peripheral clocks in the generated
MX_xxx_Init()function, but calling a HAL function beforeMX_xxx_Init()runs (or calling the wrong init) results in a silent failure. When a peripheral does not work after CubeMX configuration, verify that__HAL_RCC_xxx_CLK_ENABLE()is called before the first peripheral access. - Trusting CubeMX without understanding the clock tree — CubeMX generates a valid clock tree from the graphical configuration, but the engineer must understand PLL source, prescalers, and peripheral bus clocks well enough to configure them correctly for the application's timing and power requirements. See STM32 clock tree explained.
- Incorrect NVIC priority configuration with FreeRTOS — STM32 with FreeRTOS requires that any ISR calling FreeRTOS API functions from ISR (
...FromISR()) has a numeric priority value equal to or higher thanconfigMAX_SYSCALL_INTERRUPT_PRIORITY. ISRs at higher priority (lower number) than this threshold cannot safely call FreeRTOS API functions; doing so causes hard faults. See How Do You Configure STM32 NVIC Interrupt Priorities? for the full priority model and FreeRTOS configuration, and the STM32 GPIO interrupt not firing forum discussion for a related debug walkthrough. - Not configuring the GPIO alternate function — STM32 peripherals use GPIO pins in alternate function mode. CubeMX should configure this automatically when a pin is assigned to a peripheral, but manually written initialisation code or a modified init sequence can leave GPIO pins in the default input mode, causing the peripheral to malfunction silently.
- Using HAL_Delay() in production firmware — HAL_Delay() is a blocking delay using SysTick. It blocks the CPU for its entire duration, preventing any interrupt handling or RTOS task switching while it runs. Replace with RTOS task delays (
osDelay(),vTaskDelay()) or non-blocking timer callbacks in production firmware.
Common Questions
How do I choose between the STM32F4, STM32G4, and STM32H7?
The STM32F4 (Cortex-M4 at up to 180 MHz) is a mature, well-documented series suitable for most general-purpose embedded products. The STM32G4 (Cortex-M4 at up to 170 MHz) has a more advanced digital peripherals set including high-resolution timers (HRTIM), and better power consumption than the F4 — it is often the better choice for new F4-style designs. The STM32H7 (Cortex-M7 at up to 550 MHz) is for high-performance applications requiring significant compute, Ethernet, or camera/display interfaces. Choose the smallest, cheapest family that meets your performance and peripheral requirements, then select the specific part based on memory, package, and peripheral count.
Why is my STM32 peripheral not working after CubeMX configuration?
Common causes: the peripheral clock is not enabled (CubeMX enables it in the generated MX_xxx_Init function — verify __HAL_RCC_xxx_CLK_ENABLE() is called before using the peripheral); the GPIO alternate function is not configured (CubeMX should set this automatically when you assign a peripheral to a pin, but verify in the generated MX_GPIO_Init); the wrong UART/SPI/I2C instance is selected (STM32 has multiple instances; CubeMX generates instance-specific code). See the forum discussion STM32 GPIO interrupt not firing for a debugging walkthrough.
What is the ST-Link and do I need one?
The ST-Link is ST's debug and programming adapter for STM32 (and STM8) microcontrollers. It connects to the SWD port on the target and to USB on the host PC. You need one (or a compatible third-party SWD adapter) to program and debug STM32 in development. ST Discovery and Nucleo evaluation boards include an on-board ST-Link that can be used with an external target. For production programming without debug, a standalone J-Link, CMSIS-DAP adapter, or the STM32's built-in bootloader with dfu-util are all options. Zeus Design develops STM32 firmware for commercial product applications.
Knowledge Base
MCU Selection
- Which STM32 Family Should You Use? — G0 vs G4 vs F4 vs H7 vs L4 vs U5 vs WB vs WL: performance tiers, power profiles, peripheral sets, and which family to choose for your application
Peripheral Configuration
- How Do You Configure STM32 Peripherals with STM32CubeMX? — CubeMX workflow for GPIO, timers, SPI, I2C, UART, ADC, and DMA configuration with HAL code generation
- How Do You Configure STM32 HAL DMA for UART, SPI, and ADC? — DMA stream/channel architecture, Normal vs Circular mode, DMA with UART/SPI/ADC, interrupt callbacks, double buffering, and D-cache coherency on STM32H7/F7
Clock Tree
- STM32 Clock Tree Explained — HSI, HSE, PLL, SYSCLK, AHB, APB, and peripheral clock configuration; common mistakes in clock setup
Bootloader and Firmware Update
- How Do You Use the STM32 DFU Bootloader to Flash Firmware? — BOOT0 configuration, system memory boot, dfu-util over USB, and the application jump sequence
Interrupts and NVIC
- How Do You Configure STM32 NVIC Interrupt Priorities? — 4-bit priority model, preemption vs sub-priority, HAL_NVIC_SetPriority, priority grouping, and the FreeRTOS configMAX_SYSCALL_INTERRUPT_PRIORITY constraint with worked examples
Debugging and Firmware
- How Do You Debug Embedded Firmware? — JTAG/SWD, ST-Link, breakpoints, register view, and SWO trace with STM32CubeIDE
Forum Discussions
STM32F401 UART printing garbage after switching to 84 MHz PLL — same 115200 baud in CubeMX and PuTTY
Got a WeAct Black Pill (STM32F401CCU6) project that's been running happily on the default HSI clock at 16 MHz. Using USART1 on PA9/PA10 thro
STM32H743 HAL_UART_Receive_DMA fires error callback immediately — TEIF1 set, RxCplt never fires
Upgrading a project from STM32F4 to STM32H743. UART DMA receive worked on the F4 without any issues — standard CubeMX setup, call HAL_UART_R
STM32 GPIO interrupt configured but ISR never fires — what am I missing?
Trying to use a button on PA0 to trigger an interrupt on an STM32F411 Nucleo board. Using HAL, generated the init code with CubeMX. The GPIO
STM32 USB not detected by Windows after jumping to bootloader mode
Working on a custom STM32F411 board, trying to jump into the built-in USB DFU bootloader from application code instead of holding BOOT0 on p