🛠 Bare-metal sur le STM32F401 : clignoter LD2 en écrivant les registres GPIO

STM32 Nucleo-64 famille F4 — phare : Nucleo-F401RE · avance · Schéma : IMG-stm32f4-nucleo-avance-7-stm32f4nuc-baremetal-registres-gpio.svg — carte mémoire du STM32F401 avec GPIOA en 0x40020000, registres MODER et ODR zoomés, RCC_AHB1ENR en 0x40023830, flèches vers la broche PA5 et sa LED LD2

Goals

Strip away HAL, CMSIS device headers and the startup file, and blink LD2 by writing GPIO registers directly. This is the fastest way to understand what every abstraction above is doing — and it shows what the Cortex-M4F at 84 MHz gives you for the price of a Nucleo-64 board.

Hardware

The memory map (RM0368)

Code

/* blink_bare.c — arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -O2 -nostdlib */
#define GPIOA_MODER (*(volatile unsigned int *)0x40020000u)
#define GPIOA_ODR   (*(volatile unsigned int *)0x40020140u)
#define RCC_AHB1ENR (*(volatile unsigned int *)0x40023830u)

static void busy_wait(void) { for (volatile int i = 0; i < 2000000; ++i) {} }

void Reset_Handler(void)
{
    RCC_AHB1ENR  |= (1u << 0);   /* enable GPIOA clock (default HSI 16 MHz) */
    GPIOA_MODER  &= ~(3u << 10);
    GPIOA_MODER  |=  (1u << 10); /* PA5 -> general-purpose output           */
    while (1) {
        GPIOA_ODR ^= (1u << 5);  /* toggle LD2                              */
        busy_wait;
    }
}

Steps

  1. Write a minimal linker script placing the vector table at 0x0800_0000: initial stack pointer, then the address of Reset_Handler.
  2. Compile: arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -O2 -nostdlib -nostartfiles -T flash.ld blink_bare.c -o blink_bare.elf
  3. Flash over the on-board ST-LINK with STM32CubeProgrammer (or drop the binary on the ST-LINK mass-storage function).
  4. Press RESET: LD2 toggles.

Expected result

A steady heartbeat on PA5 with a binary of a few dozen bytes. Every HAL_GPIO_WritePin you ever wrote is this, plus clock trees, plus the vector table, plus a startup file — the HAL call hides bookkeeping, not magic.

Common mistakes

Autres tutoriels pour cette carte

Exemples de code pour cette carte

← Retour à la fiche 🛠 Tous les tutoriels