Cuando el compilador GCC de tu STM32 traduce tu código, busca hacerlo lo más rápido posible. Si detecta un bucle while(1) que lee constantemente la variable pulsos_sensor, piensa: "Leer la memoria SRAM toma 3 ciclos de reloj. Mejor leo la RAM una sola vez, copio el valor a un registro interno de la CPU (como R0, que toma 0 ciclos) y asumo que nunca va a cambiar". A esto se le llama "Caché de Registro".
Tu flujo principal (Súper Bucle) está revisando ciegamente su registro R0. Mientras tanto, el gas fluye, el caudalímetro gira y envía señales eléctricas. Estas señales disparan una Interrupción de Hardware (ISR) que pausa la CPU, actualiza la variable física en la SRAM y devuelve el control. El Súper Bucle, con su R0 "optimizado", jamás se enterará de que el valor real en la RAM cambió. El sistema colapsa.
Colocar la palabra clave volatile delante de una declaración (ej. volatile uint32_t pulsos;) es una orden militar estricta para el compilador: "Esta variable puede mutar en cualquier instante por fuerzas que no comprendes. Queda estrictamente prohibido optimizarla. Debes caminar hasta la memoria física SRAM y leerla de nuevo en cada maldita iteración."
Ejercicio 1: Simularemos la lectura del caudalímetro en una Interrupción (ISR). Verás la forma de declarar la variable metrológica de modo que tu Súper Bucle pueda vigilarla sin caer en la trampa de la optimización del compilador.
#include <stdint.h>
#include <stdbool.h>
// --- 1. DEFINICIONES HARDWARE ---
#define META_PULSOS 1500 // Equivalente a un despacho de 15 Litros
extern void Cerrar_Electrvalvulas(void); // HAL del Día 007
// --- 2. LA VARIABLE METROLÓGICA (EL CORAZÓN DEL PROBLEMA) ---
// INCORRECTO: El compilador en modo -O2/-O3 cacheará esto en un registro (R0).
// uint32_t pulsos_totales = 0;
// CORRECTO: Obligamos al compilador a leer siempre la memoria SRAM física.
volatile uint32_t pulsos_totales = 0;
// Bandera de seguridad. También debe ser volatile porque la modifica la interrupción.
volatile bool despacho_completado = false;
// --- 3. RUTINA DE SERVICIO DE INTERRUPCIÓN (ISR) ---
// Esta función NO es llamada por tu código. Es disparada por el Hardware
// (ej. el pin PA0 del STM32) cada vez que el aspa del flujómetro gira y emite 5V.
void EXTI0_Flujometro_ISR(void) {
// La interrupción detiene el procesador, suma 1, y devuelve el control
pulsos_totales++;
}
// --- 4. SÚPER BUCLE DE CONTROL ---
int main(void) {
// Iniciar hardware y válvulas...
while(1) {
// Al usar 'volatile', el STM32 debe ejecutar una instrucción "LDR" (Load Register)
// desde la dirección real de SRAM en cada vuelta de este bucle.
if (pulsos_totales >= META_PULSOS) {
if (!despacho_completado) {
Cerrar_Electrvalvulas(); // ¡Corte Metrológico Seguro!
despacho_completado = true;
}
}
// Polling de HMI o Telemetría...
}
return 0;
}
Objetivo del día: Interfaz de Hardware Asíncrono Segura.
El fluido del Gas LP no espera a que tu procesador termine de calcular el ticket o dibujar en la pantalla. Un flujómetro de alta precisión emite cientos de pulsos eléctricos por segundo. La única forma de no perder un solo mililitro es mediante Interrupciones de Hardware (EXTI). Al blindar la variable pulsos_totales con volatile, lograste que tu Súper Bucle (software) y tu Flujómetro (hardware) puedan comunicarse de forma 100% asíncrona sin que el optimizador del compilador se interponga y ciegue a la máquina.
volatile desactiva esta optimización local. Ordena una lectura directa a la memoria SRAM física cada vez que se menciona la variable.main() y una ISR, o que represente un registro de hardware (ej. GPIOA_IDR), debe ser marcada obligatoriamente como volatile.1. Si olvidamos poner volatile en la variable despacho_completado y una interrupción de emergencia la pusiera en true, ¿qué pasaría en el Súper Bucle?
Respuesta: El bucle seguiría evaluándola como false para siempre. El compilador, al no ver ninguna línea dentro del while(1) que modifique esa variable, asume que siempre será falsa. Las válvulas de gas nunca se cerrarían en caso de emergencia, lo que subraya por qué el dominio de volatile es literalmente una cuestión de seguridad industrial.