🛠 Bare metal total : clignoter PC13 en écrivant aux registres (CMSIS)
El principio
Un STM32F103 es una tarjeta de registros de memoria. Todo firmware, desde el proyecto Cube más grande hasta el blink más pequeño, se reduce a: activar el reloj del periférico, configurar los pines y escribir bits. Las definiciones utilizadas aquí provienen únicamente del encabezado CMSIS oficial de ST, stm32f103xb.h (repositorio STMicroelectronics/cmsis_device_f1).
El código completo
/* 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;
}
}
Los cuatro conceptos a recordar
- Puertas de reloj: cada periférico tiene su bit en
RCC->APB2ENR(GPIOC, USART1, SPI1, ADC1…) oAPB1ENR(USART2/3, SPI2, CAN1, los temporizadores…). Olvidar esta línea es el bug bare-metal n.º 1: los registros parecen leer 0 y nada se mueve. - CRH/CRL: en F1, cada pin GPIO se configura mediante 4 bits (MODE+CNF) en CRL (pines 0–7) o CRH (8–15). PC13 cae en CRH, bits 23:20.
- BSRR/BRR: escrituras atómicas sobre ODR sin lectura-modificación-escritura — seguro incluso si una interrupción afecta al mismo puerto.
- El cableado del LED: dado que el LED de usuario está entre VCC y PC13 (modo sink, stm32-base), es BRR (poner a 0) el que lo enciende.
Limitaciones de PC13
El pin PC13 es un pin de control con capacidad reducida en F103 — de ahí el modo salida 2 MHz en todos los ejemplos.
Para ir más allá: el enlace flash.ld (flash en 0x8000000, 64 KB; RAM 20 KB), una tabla de vectores correcta y el arranque mediante Reset_Handler — o deje que CubeMX genere estas bases, y luego léalas línea por línea.
Otros tutoriales para esta placa
- 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