DÍA 035 DE 365

Fase 1: Fundamentos de C y Lógica de Software

📖 Teoría Explícita: Modulación por Ancho de Pulso (PWM)

La **Modulación por Ancho de Pulso** (PWM, por sus siglas en inglés) es una técnica digital para simular señales analógicas o controlar la potencia entregada a una carga variando la proporción de tiempo en que la señal digital está activa (HIGH) dentro de un período constante.

Para generar una señal PWM mediante hardware interno se utilizan tres registros principales del temporizador:

Ecuaciones de PWM

El Ciclo de Trabajo (Duty Cycle, $D$) representa el porcentaje de tiempo activo en un período:

$$ D = \left(\frac{t_{ON}}{T}\right) \times 100\% = \left(\frac{CCR}{ARR + 1}\right) \times 100\% $$

El voltaje promedio equivalente ($V_{prom}$) aplicado al componente es directo a su ciclo de trabajo:

$$ V_{prom} = V_{max} \times \left(\frac{D}{100}\right) $$

GENERACIÓN DE PWM POR COMPARACIÓN DE REGISTROS Valor CNT ARR CCR (50%) Pin PWM t_ON t_OFF Período T

⚡ Circuito e Interfaz de Transductor

Un pin GPIO de microcontrolador solo entrega una corriente limitada (típicamente 8 a 20 mA). Para manejar un Buzzer acústico o la modulación de una válvula proporcional, se requiere una etapa de potencia de desacoplamiento con un transistor BJT o MOSFET.

Componente Hardware Conexión / Pin MCU Propósito en el Sistema
Buzzer Piezoeléctrico Pasivo TIM3_CH1 (Ej. Pin PA6) vía Transistor NPN (2N2222) Retroalimentación auditiva (Beeps) al pulsar el teclado capacitivo.
Resistencia de Base ($R_B$) 1 kΩ entre Pin MCU y Base del Transistor Limitación de corriente para la conmutación saturada del BJT.
Diodo Antiparalelo (Flyback) 1N4148 en paralelo con la carga inductiva/piezo Protección contra picos de tensión inducida en conmutación.

⚙️ Código C: Control Dinámico de Tono y Duty Cycle

El siguiente código muestra cómo cambiar dinámicamente la frecuencia y el Ciclo de Trabajo ($CCR$) de un canal Timer PWM en C para generar patrones de audio breves (Beeps de confirmación) al interactuar con la interfaz.


#include <stdint.h>
#include <stdbool.h>

// Registros abstractos simulados de Hardware PWM (Timer 3, Canal 1)
typedef struct {
    volatile uint32_t CR1;
    volatile uint32_t PSC;
    volatile uint32_t ARR;
    volatile uint32_t CCR1;
} PWM_Timer_TypeDef;

#define TIM3_BASE ((PWM_Timer_TypeDef *) 0x40000400)

/**
 * @brief Configura la frecuencia y el duty cycle del PWM para el Buzzer.
 * @param frecuencia_hz Frecuencia deseada del tono en Hz.
 * @param duty_porcentaje Ciclo de trabajo (0 a 100 %).
 */
void PWM_EstablecerTono(uint32_t frecuencia_hz, uint8_t duty_porcentaje) {
    if (frecuencia_hz == 0 || duty_porcentaje == 0) {
        // Silenciar PWM
        TIM3_BASE->CCR1 = 0;
        return;
    }

    uint32_t reloj_timer = 84000000; // 84 MHz
    uint32_t prescaler = 83;         // F_cnt = 1 MHz (1 tick = 1 us)

    // Período total = 1,000,000 us / Frecuencia
    uint32_t arr_valor = (1000000 / frecuencia_hz) - 1;
    
    // Asignación de registros
    TIM3_BASE->PSC = prescaler;
    TIM3_BASE->ARR = arr_valor;

    // Cálculo del valor del registro Compare según el Duty Cycle
    if (duty_porcentaje > 100) duty_porcentaje = 100;
    TIM3_BASE->CCR1 = ((arr_valor + 1) * duty_porcentaje) / 100;
}

/**
 * @brief Emite un beep rápido de confirmación acústica no bloqueante.
 */
void EmitirBeepTeclado(void) {
    // Generar tono claro de 2.7 kHz al 50% de volumen/potencia
    PWM_EstablecerTono(2700, 50);
}

void DetenerTono(void) {
    PWM_EstablecerTono(0, 0);
}

int main(void) {
    // En el inicio del sistema
    PWM_EstablecerTono(0, 0);

    while (1) {
        // Simulación: Si se detecta un toque válido en el Teclado Capacitivo 4x4
        bool tecla_presionada = false; // Bandera procedente del driver I2C

        if (tecla_presionada) {
            EmitirBeepTeclado();
            // Utilizar un Timer No-Bloqueante para llamar DetenerTono() a los 50ms
        }
    }
    return 0;
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Confirmación Auditiva para Panel Capacitivo e Interfaz HMI.

Al no existir botones mecánicos con "clic" en el teclado 4x4 capacitivo que diseñaste en KiCad, el usuario carece de la sensación de respuesta física. La implementación de modulación PWM dedicada te permite activar tonos audibles limpios e instantáneos ante cada pulsación confirmada por I2C. Esto eleva la seguridad y usabilidad del Despachador de Gas LP en entornos industriales ruidosos, informando al operador que la orden de despacho o comando de seguridad ha sido aceptado por el firmware.

📝 Resumen del Día

❓ Cuestionario de Autoevaluación

1. Si un Timer tiene un registro $ARR = 1999$ y se configura un valor $CCR1 = 500$, ¿cuál es el ciclo de trabajo (Duty Cycle) resultante?
Respuesta: Usando la fórmula: $D = \frac{CCR}{ARR + 1} \times 100\% = \frac{500}{2000} \times 100\% = 25\%$.

2. ¿Por qué se prefiere ajustar el brillo de una pantalla o la velocidad de un motor mediante PWM en lugar de usar una resistencia variable analógica?
Respuesta: Por eficiencia energética. En PWM el transistor commuta entre corte (corriente 0) y saturación (caída de voltaje casi 0), minimizando la disipación de calor por potencia ($P = V \times I$), a diferencia de un elemento lineal que disipa el exceso en forma de calor.