Cada pin físico de tu microcontrolador (como el PA5 que usamos de referencia) no es un simple alambre. Por dentro del silicio, está conectado a un circuito digital complejo llamado GPIO Port (General Purpose Input/Output). Para configurar este pin a nivel de registro, debemos interactuar con cuatro registros clave:
00 = Entrada, 01 = Salida digital, 10 = Función alternativa (ej. UART/SPI), 11 = Modo analógico (para el ADC).Un error clásico de principiante es modificar los pines usando el registro ODR (Output Data Register) mediante operadores de bits directos como GPIOA->ODR |= (1 << 5);. Esto es un peligro en sistemas industriales multitarea. El compilador traduce esa línea en tres pasos en ensamblador: Leer ODR, Modificar el bit, Escribir ODR. Si ocurre una interrupción exacta entre la lectura y la escritura, tu cambio de estado se corromperá.
Para evitar esto, ARM diseñó el registro BSRR (Bit Set/Reset Register). Es un registro de escritura única atómica: si escribes un 1 en la mitad superior pones en 0 el pin, y si escribes un 1 en la mitad inferior pones en 1 el pin. Todo en un solo ciclo de reloj y sin riesgo de interferencia.
Ejercicio 1: Escribe el programa completo en C utilizando CMSIS puro para inicializar el reloj del puerto A, configurar el pin PA5 como salida digital Push-Pull sin resistencias internas, y activar la válvula/relé de gas de forma intermitente en un bucle infinito de alta velocidad.
/**
* @file main.c
* @brief Control GPIO a Nivel de Registro (Bare-Metal CMSIS)
*/
#include "stm32f401xe.h"
// Definición limpia para nuestro actuador (Válvula de Gas o LED de prueba)
#define VALVULA_GAS_PIN 5
void configurar_gpio_valvula(void) {
// 1. HABILITAR EL RELOJ DEL PERIFÉRICO (RCC)
// Sin esta línea, el puerto A está muerto eléctricamente (apagado en el bus AHB1)
RCC->AHB1ENR |= (1 << 0); // Bit 0 corresponde a GPIOA
// 2. CONFIGURAR MODO (MODER)
// Cada pin usa 2 bits. Limpiamos los bits [11:10] correspondientes al Pin 5
GPIOA->MODER &= ~(3 << (VALVULA_GAS_PIN * 2));
// Seteamos el valor '01' (Modo Salida Digital / General Purpose Output)
GPIOA->MODER |= (1 << (VALVULA_GAS_PIN * 2));
// 3. CONFIGURAR TIPO DE SALIDA (OTYPER)
// Seteamos '0' para Push-Pull (Estándar industrial de alta potencia)
GPIOA->OTYPER &= ~(1 << VALVULA_GAS_PIN);
// 4. CONFIGURAR VELOCIDAD (OSPEEDR)
// Seteamos velocidad alta '10' para respuesta inmediata ante comandos críticos
GPIOA->OSPEEDR &= ~(3 << (VALVULA_GAS_PIN * 2));
GPIOA->OSPEEDR |= (2 << (VALVULA_GAS_PIN * 2));
// 5. CONFIGURAR PULL-UP / PULL-DOWN (PUPDR)
// Sin resistencias flotantes ('00' = Ninguna)
GPIOA->PUPDR &= ~(3 << (VALVULA_GAS_PIN * 2));
}
int main(void) {
// Inicializamos los registros del puerto físico
configurar_gpio_valvula();
while (1) {
// --- ACCIÓN ATÓMICA 1: ENCENDER VÁLVULA ---
// Escribir un '1' en los primeros 16 bits activa el pin (SET)
GPIOA->BSRR = (1 << VALVULA_GAS_PIN);
// Retardo operativo simulado
for (volatile uint32_t i = 0; i < 500000; i++);
// --- ACCIÓN ATÓMICA 2: APAGAR VÁLVULA ---
// Escribir un '1' en los 16 bits superiores (offset +16) apaga el pin (RESET)
GPIOA->BSRR = (1 << (VALVULA_GAS_PIN + 16));
// Retardo operativo simulado
for (volatile uint32_t i = 0; i < 500000; i++);
}
return 0;
}
Objetivo del día: Dominio de Actuadores de Potencia a Nivel de Registro.
En tu diseño de PCB (Fase 2), el pin PA5 de tu microcontrolador viaja a través de una pista de cobre ruteada con ancho industrial hacia la compuerta de un transistor MOSFET o un optoacoplador que a su vez conmuta los 24V de la electroválvula del gas.
Al manipular el registro GPIOA->BSRR de manera atómica, garantizas que la orden de corte de emergencia ante una fuga de gas se ejecute instantáneamente en el siguiente ciclo de reloj. No hay llamadas a funciones pesadas de librerías comerciales; es electricidad pura controlada por instrucciones binarias optimizadas por GCC. Tu Despachador responde con velocidad de hardware puro.
RCC->AHB1ENR.01 lo convierte en una salida digital de propósito general.ODR para modificar pines individuales en entornos multi-hilo o con interrupciones; utiliza siempre BSRR para operaciones de escritura atómica seguras.