🛠 Bare metal total : clignoter PC13 en écrivant aux registres (CMSIS)
The principle
An STM32F103 is essentially a map of memory registers. Any firmware, from the largest Cube project to the smallest blink, boils down to: enabling the peripheral clock, configuring the pins, and writing bits. The definitions used here come exclusively from ST's official CMSIS header, stm32f103xb.h (STMicroelectronics/cmsis_device_f1 repository).
The complete code
/* 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;
}
}
The four key concepts to remember
- Clock gates: each peripheral has its bit in
RCC->APB2ENR(GPIOC, USART1, SPI1, ADC1…) orAPB1ENR(USART2/3, SPI2, CAN1, timers…). Forgetting this line is the #1 bare-metal bug: registers appear to read 0 and nothing happens. - CRH/CRL: on the F1, each GPIO pin is configured by 4 bits (MODE+CNF) in CRL (pins 0–7) or CRH (pins 8–15). PC13 falls into CRH, bits 23:20.
- BSRR/BRR: atomic writes to ODR without read-modify-write — safe even if an interrupt touches the same port.
- LED wiring: since the user LED is between VCC and PC13 (sink mode, stm32-base), it is BRR (setting to 0) that turns it on.
PC13 limitations
The PC13 pin is a reduced-capability control pin on the F103 — hence the 2 MHz output mode in all examples.
To go further: the flash.ld link (flash at 0x8000000, 64 KB; RAM 20 KB), a correct vector table, and startup via Reset_Handler — or let CubeMX generate these basics, then read them line by line.
Other tutorials for this board
- Découvrir la Blue Pill : que trouve-t-on dans la boîte ?
- Premier programme Arduino sur la Blue Pill (core officiel stm32duino)
- Alimenter et flasher la Blue Pill : BOOT0, port série, ST-Link et DFU
- Série, ADC et chasse aux contrefaçons : diagnostiquer sa Blue Pill
- Dompter l'USB natif de la Blue Pill : CDC, DFU et la résistance rebelle
- Passer au niveau supérieur : STM32CubeIDE, HAL et LL sur F103