STM32F411CEU6 hardware explorations and bare-metal templates
  • C 78.8%
  • CMake 18.5%
  • Linker Script 2.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-05 13:37:49 -07:00
01_simple_blink Initial commit of STM32 bare-metal blink and UART experiments with comparison guide 2026-08-05 13:18:53 -07:00
02_uart_systick Initial commit of STM32 bare-metal blink and UART experiments with comparison guide 2026-08-05 13:18:53 -07:00
03_hal_blink Restore 500ms delay for hal_blink 2026-08-05 13:27:56 -07:00
04_usb_mouse Switch usb_mouse to use custom C-based startup.c for reliability 2026-08-05 13:37:49 -07:00
common Switch usb_mouse to use custom C-based startup.c for reliability 2026-08-05 13:37:49 -07:00
.gitignore Initial commit of STM32 bare-metal blink and UART experiments with comparison guide 2026-08-05 13:18:53 -07:00
CMakeLists.txt Switch usb_mouse to use custom C-based startup.c for reliability 2026-08-05 13:37:49 -07:00
README.md Fix README erratum: clarify Pico 2 5V tolerance vs Pico 1 2026-08-05 13:19:58 -07:00
toolchain.cmake Initial commit of STM32 bare-metal blink and UART experiments with comparison guide 2026-08-05 13:18:53 -07:00

📊 STM32F411CEU6 (Blackpill) vs. RP2350 (Pi Pico 2) Reference Guide

If you are coming from the Pi Pico C SDK (RP2040 / RP2350), the STM32F411 will feel both familiar and distinct. While the Pi Pico 2 is a modern, general-purpose microcontroller focused on raw speed, flexible I/O, and dual cores, the STM32F411 is an industrial workhorse focused on dedicated hardware acceleration and robust, deterministic execution.


⚙️ Architectural & Hardware Comparison

Feature RP2350 (Pi Pico 2) STM32F411CEU6 (Blackpill) Takeaway for Pico Developers
CPU Core Dual ARM Cortex-M33 (or Hazard3 RISC-V) Single ARM Cortex-M4 Pico 2 is faster/multi-core. STM32 is single-core but features a very capable M4 with DSP extensions and a hardware Floating Point Unit (FPU).
Clock Speed 150 MHz 100 MHz Pico 2 runs faster, but STM32 instructions run deterministically from zero-wait-state internal flash.
Flash Memory External QSPI (usually 4MB - 8MB) 512 KB Internal Flash STM32 Flash is internal: You don't need external flash chips. However, 512KB is a hard limit (no mega-sized programs).
SRAM 520 KB 128 KB Pico 2 has 4x more RAM. On STM32, memory management (especially buffers) must be more conservative.
Operating Voltage 3.3V (Pico 2 GPIOs are 5V tolerant when powered, except ADC; Pico 1 is not) 3.3V (with 5V tolerant pins!) Many STM32 pins are 5V tolerant (marked FT in the datasheet). This is a huge help when interfacing with older 5V sensors/displays (unlike Pico 1, which is strictly 3.3V only).
USB Support USB 1.1 Device/Host USB 2.0 OTG Full Speed STM32 has a more advanced USB controller (OTG), supporting host/device modes with dedicated hardware FIFOs.

🛠️ Peripheral Differences: "Smart Hardware" vs. "Programmable I/O"

The biggest philosophical difference between the RP2350 and the STM32F411 is how they handle complex interfaces:

1. The Pico 2 approach: PIO (Programmable I/O)

On the Pico 2, if you want a custom interface (like driving WS2812B LEDs, an 8-bit parallel display, or DVI video), you write small assembly programs for the PIO state machines.

  • Pros: Infinitely flexible.
  • Cons: Consumes CPU-adjacent resources, requires learning PIO assembly.

2. The STM32 approach: Advanced Timers & Dedicated Engines

The STM32 has no PIO. Instead, it has highly specialized hardware modules designed to run completely independent of the CPU.

  • Advanced Timers (TIM1, TIM2, etc.): These are not just for PWM. They have hardware support for:
    • Quadrature Encoder Interface (QEI): Connect a rotary encoder directly to the timer pins; the hardware increments/decrements a counter register automatically without any CPU interrupts.
    • Input Capture: Measures pulse widths down to nanosecond precision entirely in hardware.
    • Complementary PWM: Used in motor control to drive H-bridges safely with hardware-inserted "dead time" (preventing short circuits).
  • DMA (Direct Memory Access): The STM32 DMA controllers are deeply integrated. You can map them to transfer data directly from an ADC to RAM, or RAM to SPI/USART, completely in the background without waking the CPU.

📂 Software Ecosystem Comparison

Development Area Pi Pico C SDK STM32 Ecosystem
SDK Style Clean, modular APIs (e.g. hardware_i2c, gpio_put). Three choices depending on your preferences:
1. STM32 HAL: High-level, official, boilerplate-heavy.
2. STM32 LL (Low-Layer): Lightweight register wrappers.
3. libopencm3: Open-source, very similar to Pico SDK.
Pin Configuration Pins can be dynamically routed to functions (gpio_set_function). Pins have fixed alternate functions (AF) mapped in the datasheet. You configure them via GPIOx_AFR registers.
Clock Trees Simple configuration helper clocks_init(). Complex Clock Tree: The STM32 clock tree allows routing the internal HSI (16MHz) or external HSE (25MHz crystal on Blackpill) through a PLL to generate separate clocks for USB (48MHz), AHB, APB1, and APB2 buses.

Since you are comfortable with the CMake/GCC compilation flow from the Pico C SDK, you have two great options for your next project:

Option A: Continue with Register-Level C (Bare-Metal)

If you want to understand how ARM microcontrollers work at the lowest level, writing registers is extremely satisfying. We can build:

  • A high-resolution delay timer using the SysTick timer.
  • A Serial console (printf) using the USART peripheral registers.
  • A basic ADC reader using registers.

Option B: Integrate libopencm3 or the STM32 HAL

If you want to build projects without writing raw register addresses every time:

  • libopencm3: A clean, open-source library that looks very similar to the Pico SDK.
  • STM32 HAL / CMSIS: The industry standard. We can fetch it via CMake's FetchContent to write standard STM32 code.