🛠 Bare metal total : clignoter PC13 en écrivant aux registres (CMSIS)

STM32F103 "Blue Pill" (STM32F103C8T6) · avance · Sans aucune bibliothèque : horloge APB2, registre CRH, écritures atomiques BSRR/BRR — et compréhension intime du Cortex-M3.

Le principe

Un STM32F103, c'est une carte de registres mémoire. Tout firmware, du plus gros projet Cube au plus petit blink, se réduit à : activer l'horloge du périphérique, configurer les broches, écrire des bits. Les définitions utilisées ici proviennent uniquement de l'en-tête CMSIS officiel de ST, stm32f103xb.h (dépôt STMicroelectronics/cmsis_device_f1).

Le code complet

/* Blink PC13 nu — arm-none-eabi-gcc -mcpu=cortex-m3 -O1 blink.c
   -nostartfiles -T flash.ld */
#include <stm32f1xx.h>          /* en-tête CMSIS device (ST) */

static void delay(void) { for (volatile int i = 0; i < 4000000; i++) __NOP; }

int main(void)
{
    /* 1. GPIOC est sur APB2 : activer sa porte d'horloge. */
    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

    /* 2. Config PC13 dans CRH (broches 8..15), champs bits 23:20.
       CNF13 = 00 (push-pull), MODE13 = 11 (sortie, 2 MHz max sur PC13). */
    GPIOC->CRH = (GPIOC->CRH & ~(0xFu << 20)) | (0x3u << 20);

    while (1) {
        GPIOC->BRR  = (1u << 13);  /* bit LOW  -> LED ALLUMÉE (câblage sink) */
        delay;
        GPIOC->BSRR = (1u << 13);  /* bit HIGH -> LED ÉTEINTE               */
        delay;
    }
}

Les quatre notions à retenir

  1. Portes d'horloge : chaque périphérique a son bit dans RCC->APB2ENR (GPIOC, USART1, SPI1, ADC1…) ou APB1ENR (USART2/3, SPI2, CAN1, les timers…). Oublier cette ligne est le bug bare-metal n°1 : les registres semblent lire 0 et rien ne bouge.
  2. CRH/CRL : sur F1, chaque broche GPIO se configure par 4 bits (MODE+CNF) dans CRL (broches 0–7) ou CRH (8–15). PC13 tombe dans CRH, bits 23:20.
  3. BSRR/BRR : écritures atomiques sur ODR sans lecture-modification-écriture — sûr même si une interruption touche le même port.
  4. Le câblage de la LED : la LED utilisateur étant entre VCC et PC13 (mode sink, stm32-base), c'est BRR (mettre à 0) qui l'allume.

Limites de PC13

La broche PC13 est une broche de commande à capacité réduite sur F103 — d'où le mode sortie 2 MHz dans tous les exemples.

Pour aller plus loin : le lien flash.ld (flash à 0x8000000, 64 Ko ; RAM 20 Ko), un vector table correcte, et le démarrage par Reset_Handler — ou laissez CubeMX générer ces bases, puis lisez-les ligne par ligne.

Autres tutoriels pour cette carte

Exemples de code pour cette carte

← Retour à la fiche 🛠 Tous les tutoriels