Getting Started with STM32 for Makers: Blue Pill, Black Pill, and STM32CubeIDE vs Bare-Metal
Every microcontroller guide on this site eventually points at the same two families: AVR-based Arduino boards for simplicity, and ESP32 for anything that needs WiFi or Bluetooth. There's a third family that gets mentioned only in passing — usually as "the chip inside your 3D printer's mainboard" — and that's ST's STM32 line of ARM Cortex-M microcontrollers. If you've flashed Klipper onto a printer board or plugged a debug probe into a Voron's toolhead board, you've already been running STM32 silicon without necessarily writing a line of code for it yourself. This guide covers what STM32 actually gives you over AVR and ESP32, how to get a "Blue Pill" or "Black Pill" board talking to your computer for the first time, and the real choice between ST's HAL/CubeMX tooling and bare-metal register programming.
Why Bother With STM32 at All
Arduino-compatible AVR boards are cheap and forgiving, and ESP32 gives you wireless connectivity almost for free. STM32 fills a different niche: real 32-bit ARM Cortex-M cores (M0, M3, M4, or M7 depending on the part) running at 48–480MHz, hardware floating-point units on the higher-end parts, far more timers and DMA channels than an AVR chip has pins, and peripheral sets (multiple CAN controllers, USB OTG, quadrature encoder inputs, 12-bit ADCs with real simultaneous sampling) that show up in industrial and automotive designs for a reason. It's also the chip family under the hood of most "smart" 3D printer mainboards (SKR, Octopus, Manta), many BLDC/FOC motor controller boards, and a huge share of commercial products you can buy at a store — which means STM32 experience transfers directly to reading and modifying open-source firmware for hardware you already own.
The trade-off is a steeper on-ramp than Arduino. There's no single "STM32 IDE" as universal as the Arduino IDE, the peripheral configuration is genuinely more involved because the chips are more capable, and datasheets run to 100+ pages per part. This guide is aimed at getting through that on-ramp efficiently rather than pretending it doesn't exist.
Picking a Board: Blue Pill vs Black Pill
BoardMCUCoreNotes Blue PillSTM32F103C8T6Cortex-M3 @ 72MHzUbiquitous, sub-$3, but famously shipped with counterfeit/relabeled flash on some clones — verify actual flash size before committing to a project that needs the full 64/128KB Black Pill (F401)STM32F401CCU6Cortex-M4 @ 84MHz, FPUUSB-C or micro-USB, native USB (no adapter needed for DFU flashing), better build quality than most Blue Pill clones Black Pill (F411)STM32F411CEU6Cortex-M4 @ 100MHz, FPUMore flash/RAM than the F401, same form factor, the current default recommendation for a general-purpose Cortex-M4 dev boardFor a first STM32 board, buy a Black Pill (F401 or F411) rather than a Blue Pill. It has native USB, a more reliable bootloader, and doesn't carry the Blue Pill's reputation for counterfeit flash chips. Keep a Blue Pill around later once you understand the toolchain — they're useful as disposable targets for board bring-up practice precisely because they're so cheap.
Getting Connected: ST-Link, DFU, and Your First Blink
Unlike Arduino, you can't just plug in a USB cable and hit upload on a stock Blue Pill — there's no bootloader listening on the USB port by default. You have three ways to get code onto the chip:
- ST-Link debug probe (recommended): A $3–15 clone ST-Link V2 dongle connects to the SWD (Serial Wire Debug) pins — SWDIO, SWCLK, GND, and 3V3 — exactly like the debug probe wiring covered in this site's Flipper Zero JTAG/SWD guide. This is the only method that gives you real hardware breakpoints and single-stepping through OpenOCD and GDB, and it's the method every serious STM32 workflow eventually standardizes on.
- USB DFU bootloader: Black Pill boards and F103 chips with the factory bootloader intact can be put into DFU mode (hold BOOT0 while resetting) and flashed over native USB with dfu-util or STM32CubeProgrammer, no extra hardware needed. Slower iteration than ST-Link and no debugging, but zero-cost to try.
- USB-to-serial adapter: The oldest method — an FTDI or CP2102 adapter into the chip's UART1 pins, using the built-in UART bootloader. Works everywhere but is the slowest and offers no debug visibility at all.
For a first blink, the fastest reliable path is PlatformIO inside VS Code targeting the "genericSTM32F4" (Black Pill) board definition, flashing over an ST-Link. Install the ST-Link udev rules on Linux, wire SWDIO/SWCLK/GND/3V3 from the probe to the four corresponding pins on the Black Pill, select the Arduino framework in platformio.ini for a gentle start, and pio run -t upload. Once that LED blinks, you have a working toolchain and can start moving toward the framework choice that actually matters for serious projects.
Arduino Framework, HAL/CubeMX, or Bare-Metal Registers
STM32 development splits into three layers, and which one you use is the single biggest decision in how a project will feel:
ApproachWhat it isBest for Arduino framework (STM32duino)digitalWrite()/analogRead()-style API on top of HAL, same sketch structure as any Arduino boardPorting an existing Arduino sketch to a faster/cheaper chip with minimal rewriting STM32Cube HAL + CubeMXST's official hardware abstraction layer, generated and configured graphically through the CubeMX pin/peripheral tool, then filled in with your application code in STM32CubeIDEReal projects that need to actually use STM32's peripheral set — multiple timers with input capture, DMA-driven ADC, CAN, USB device classes Bare-metal registers (CMSIS only)Direct reads/writes to peripheral registers, no abstraction layer at all beyond the CMSIS core headersLearning how the chip actually works, squeezing out maximum performance/determinism, or targeting a chip variant CubeMX doesn't fully supportStart with the Arduino framework only if you're porting something and want to move fast. For anything you intend to keep developing, learn CubeMX/HAL instead — it's the path with the most documentation, the most example code you'll find in the wild for a given peripheral, and the one that scales to the full STM32 lineup rather than the narrow subset STM32duino supports well. Save bare-metal register work for after you understand what HAL is doing for you; jumping straight to registers without that context just means re-deriving clock tree configuration and interrupt vector setup from the reference manual by trial and error.
The Clock Tree: STM32's Biggest Gotcha for Arduino Refugees
The single most common source of "it doesn't work and I don't know why" on STM32 is the clock tree. Unlike an AVR chip that mostly just runs at its crystal frequency, STM32 parts have a configurable PLL feeding a whole tree of prescalers — system clock, AHB bus, APB1 and APB2 peripheral buses (often capped at different maximum frequencies from each other), and independent clocks for USB, ADC, and RTC. Get the PLL configuration wrong and you can end up with a chip that boots but runs UART baud rates at the wrong speed, or a USB peripheral that simply never enumerates because its 48MHz requirement wasn't met. CubeMX's clock configuration tab exists specifically to keep you from doing this math by hand and will flag conflicts in red before you generate code — use it even if you're otherwise writing everything by hand, just to get a validated clock tree to reference.
Where STM32 Actually Wins Over ESP32 for Motor and Timing Work
If your project is sensor logging or a WiFi dashboard, stay on ESP32 — you already have a full wireless stack and this site's existing ESP32 content to lean on. Reach for STM32 specifically when you need hard real-time behavior: multiple independent hardware timers with input capture and PWM output on the same chip (useful for reading quadrature encoders while simultaneously driving motor PWM), a genuine floating-point unit for control-loop math without software emulation overhead, or CAN bus support built into the silicon rather than bolted on through an external controller like the MCP2515 covered in this site's CAN bus guide. FOC (field-oriented control) motor drivers and multi-axis motion controllers are the classic STM32 use case for exactly this reason.
Common First-Project Pitfalls
- BOOT0 left floating on a bare F103: Many minimal Blue Pill boards need BOOT0 pulled low for normal flash boot and high only when entering the bootloader — if your board doesn't have the jumper, you may need to add one.
- 3.3V-only I/O: STM32 GPIO is not 5V tolerant on most pins the way many AVR chips are — check the datasheet's "FT" (5V-tolerant) pin markings before wiring up a 5V sensor directly, and use the same level-shifting approach covered in this site's logic level shifter guide otherwise.
- Counterfeit flash on cheap Blue Pill clones: Some clone boards report a smaller genuine flash size behind an alias that makes CubeProgrammer see 128KB when only 64KB is real — if a project mysteriously corrupts data past a certain flash address, this is worth ruling out.
- Forgetting HAL_Init() and SysTick: HAL's delay and timeout functions depend on a working SysTick interrupt; if you've hand-rolled interrupt priority configuration and disabled it, HAL_Delay() will simply hang forever.
STM32 is worth the extra setup friction the first time you need real-time determinism, more timers than you have fingers, or a chip family whose firmware you'll actually be able to read when it's already running inside a printer mainboard or motor controller you own. Start on a Black Pill with an ST-Link, go through CubeMX once by hand so the clock tree and peripheral setup stop feeling like magic, and the rest of the ARM Cortex-M ecosystem — including the Cortex-M0/M3 chips inside a huge share of commercial products — opens up from there.
Related Guides
- CH32V003 and RISC-V Microcontrollers for Makers: Sub-Dollar Alternatives to AVR and ESP32
- STM32 Nucleo-F411RE
- STM32 "Blue Pill" (STM32F103C8T6)
- How to Use the Flipper Zero GPIO for Hardware Hacking: UART, SPI, I2C, and Debugging
- Raspberry Pi Pico — First Steps with MicroPython
- Arduino vs ESP32: Which Should You Use? A Practical Comparison
- Flipper Zero GPIO Pinout and Hardware Expansion: UART, I2C, ADC, 1-Wire, and Sensor Wiring
- Getting Started with ESP32: GPIO, WiFi, and Your First Project