DÍA 104 DE 365

Fase 2: Fundamentos de Hardware y Electrónica

📖 Teoría a Estudiar

Multitarea Asíncrona por Hardware

Un error común es intentar hacer todo dentro del SysTick (el timer de 1ms). Si colocas la función de refrescar la pantalla LCD dentro del SysTick, la pantalla exigirá unos 3 milisegundos para comunicarse por I2C. ¡Tu interrupción tardaría más en ejecutarse que el tiempo límite para la siguiente interrupción! Esto colapsaría la máquina.

La solución en arquitecturas de alto rendimiento (Bare-Metal) es distribuir la carga temporal utilizando diferentes Hardware Timers, cada uno con una frecuencia distinta y una prioridad específica en el NVIC.

Matemática para 10 Hz (100 ms)

Usaremos el TIM3 para nuestra interfaz de usuario. Nuestro reloj base es de $84,000,000\text{ Hz}$. La ecuación es $f = f_{CLK} / ((\text{PSC}+1)(\text{ARR}+1))$.

ARQUITECTURA DE EVENTOS CONCURRENTES (TIME-SLICING) Línea de Tiempo Físico 0 ms 500 ms 1000 ms (1s) SysTick 1000 Hz (1ms) ... Micro-tareas (Watchdog, Debounce) TIM3 10 Hz (100ms) Draw LCD Draw LCD TIM2 1 Hz (1s) Calc LPM

⚙️ Ejercicios Prácticos

Ejercicio 1: Configura el TIM3 para que levante una interrupción cada 100 milisegundos (10Hz). Dentro de la Rutina de Servicio de Interrupción (ISR), levanta una "bandera" (flag) para que el `main()` sepa que es el momento exacto de actualizar la Interfaz Humano-Máquina (HMI).


/**
 * @file main.c
 * @brief Tareas Periódicas de Mediana Frecuencia (10Hz) con TIM3
 */

#include "stm32f401xe.h"
#include <stdbool.h>

// Bandera de sincronización (Hardware -> Software)
volatile bool flag_actualizar_pantalla = false;

void inicializar_timer3_10Hz(void) {
    
    // 1. Habilitar reloj del periférico TIM3 en el bus APB1
    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
    
    // 2. Configurar Prescaler (PSC)
    // TIM_CLK = 84 MHz. Dividimos entre 8400 para obtener un tick de 10 kHz (0.1ms)
    TIM3->PSC = 8400 - 1;
    
    // 3. Configurar Auto-Reload Register (ARR)
    // 10,000 Hz / 1000 = 10 Hz (100 ms de periodo)
    TIM3->ARR = 1000 - 1;
    
    // 4. Habilitar la interrupción por desbordamiento (Update Event)
    TIM3->SR &= ~TIM_SR_UIF; // Limpiar bandera remanente
    TIM3->DIER |= TIM_DIER_UIE;
    
    // 5. Configurar el Árbitro (NVIC)
    // Le daremos prioridad baja (ej. 12), ya que actualizar una pantalla 
    // no es tan crítico como cerrar una válvula o atrapar un pulso de gas.
    NVIC_SetPriority(TIM3_IRQn, 12);
    NVIC_EnableIRQ(TIM3_IRQn);
    
    // 6. Encender el contador
    TIM3->CR1 |= TIM_CR1_CEN;
}

// ISR del Timer 3 (Se dispara 10 veces por segundo)
void TIM3_IRQHandler(void) {
    
    if (TIM3->SR & TIM_SR_UIF) {
        
        // En lugar de enviar los datos por I2C aquí mismo (lo cual bloquearía 
        // el procesador), solo levantamos una bandera.
        flag_actualizar_pantalla = true;
        
        // Limpiamos la bandera física de hardware
        TIM3->SR &= ~TIM_SR_UIF;
    }
}

int main(void) {
    
    // (Asumimos inicialización de RCC a 84MHz y Pantalla LCD)
    inicializar_timer3_10Hz();
    
    while(1) {
        
        // El Súper Bucle atiende las tareas cuando el hardware le avisa
        if (flag_actualizar_pantalla) {
            
            // Bajamos la bandera inmediatamente
            flag_actualizar_pantalla = false;
            
            // Esta función pesada se ejecuta "a demanda" cada 100ms exactos
            // lcd_i2c_escribir_dinero(litros_actuales * PRECIO_POR_LITRO);
        }
        
    }
    
    return 0;
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Experiencia de Usuario (UX) fluida mediante Hardware.

Piensa en el cliente observando la pantalla de tu Despachador. Si actualizas la cantidad de dinero a pagar muy lento (ej. cada segundo con el TIM2), los números saltarán de forma brusca ($10... $18... $26), generando desconfianza. Si intentas actualizarla miles de veces por segundo, la pantalla LCD I2C se saturará, mostrando caracteres corruptos y bloqueando el CPU.

Al utilizar el TIM3 configurado a 10Hz, logras el balance dorado. Cada 100 milisegundos, el hardware le da un ligero "toque" al software levantando la bandera flag_actualizar_pantalla. El bucle `main` ve la bandera, pinta el nuevo precio en la pantalla, y sigue su camino. El cliente ve cómo los números corren fluidamente como en una gasolinera comercial, y el microcontrolador ni siquiera "suda" con el esfuerzo.

📝 Resumen del Día