Introducción a los Temporizadores de Control Avanzado (TIM1 y TIM8)
Los periféricos TIM1 y TIM8 en los microcontroladores STM32 representan la cumbre de la precisión en temporización. A diferencia de los temporizadores básicos o generales, los de control avanzado integran características diseñadas específicamente para el control de motores industriales y la conversión de potencia. Sus funciones clave incluyen salidas complementarias con tiempos muertos (dead-time) programables, contadores de repetición y mecanismos de protección (freno/break).
La unidad base de tiempo consta de un contador de 16 bits (CNT), un pre-escalador programable (PSC) de 16 bits y un registro de auto-recarga (ARR). Una adición fundamental es el registro de repetición (RCR) de 8 bits, que permite extender la flexibilidad de la temporización hasta niveles equivalentes a 40 bits de resolución efectiva en eventos específicos.
Fuentes de Reloj y Sincronización
Para garantizar la versatilidad en diversas aplicaciones, estos temporizadores pueden recibir señales de reloj desde cuatro fuentes distintas:
- Reloj Interno (CK_INT): Generalmente derivado del bus APB, operando comúnmente a 72 MHz en dispositivos de alto rendimiento.
- Modo de Reloj Externo 1: Utiliza los pines de entrada del temporizador (TI1, TI2, TI3, TI4) como disparadores de conteo.
- Modo de Reloj Externo 2: Emplea el pin ETR (External Trigger) con opciones de filtrado y pre-escalado dedicadas.
- Disparador Interno (ITRx): Permite el encadenamiento de temporizadores, donde uno actúa como maestro y otro como esclavo para sincronización compleja.
Configuración de la Unidad de Tiempo
El comportamiento del contador puede ajustarse en tres modos de conteo:
- Modo Ascendente: El contador incrementa desde 0 hasta el valor de ARR, genera un evento de actualización y reinicia.
- Modo Descendente: El contador decrece desde el valor de ARR hasta 0, genera el evento y reinicia al valor ARR.
- Modo Alineado al Centro: El contador oscila entre 0 y ARR-1 (ascendente) y luego de ARR a 1 (descendente). Este modo es esencial para reducir armónicos en el control de motores mediante PWM.
Captura de Entrada (Input Capture)
Esta función permite medir parámetros de señales externas, como la frecuencia y el ancho de pulso. Cuando ocurre una transición válida en un pin de entrada, el valor actual del contador se "captura" en un registro de comparación (CCR). Al calcular la diferencia entre dos capturas sucesivas, se obtiene el periodo de la señal.
El modo PWM Input es un caso especial donde una sola señal de entrada utiliza dos canales de captura. Uno se configura para detectar el flanco de subida (periodo) y el otro para el flanco de bajada (ciclo de trabajo), automatizando la medición sin intervención constante de la CPU.
Comparación de Salida y Generación de PWM
Los temporizadores avanzados pueden generar señales PWM con un control granular sobre la polaridad y el estado de la salida. Existen ocho modos de comparación, siendo PWM1 y PWM2 los más utilizadso.
Gestión de Tiempos Muertos (Dead-time)
En configuraciones de medio puente o puente completo (H-Bridge), es crítico evitar que dos transistores de una misma rama conduzcan simultáneamente, lo que provocaría un cortocircuito. El generador de tiempo muerto inserta un retraso configurable entre la desactivación de una señal y la activación de su complementaria (OCx y OCxN).
Estructuras de Configuración en la Biblioteca Estándar (SPL)
El manejo de estos periféricos se facilita mediante estructuras de datos que definen su comportamiento inicial.
Base de Tiempo
typedef struct {
uint16_t ClockPrescaler; // Valor para el registro PSC
uint16_t Mode_Counter; // Ascendente, descendente o centrado
uint32_t AutoReloadValue; // Valor para el registro ARR
uint16_t Clock_Div; // Divisor para filtros y tiempo muerto
uint8_t Repetition_Count; // Registro RCR para eventos avanzados
} Advanced_TimeBase_Config;
Configuración de Salida PWM
typedef struct {
uint16_t PWM_Mode; // PWM1 o PWM2
uint16_t State_Output; // Habilitación de la salida principal
uint16_t State_OutputN; // Habilitación de la salida complementaria
uint32_t Duty_Pulse; // Valor de comparación (CCR)
uint16_t Polarity; // Activo en alto o bajo
uint16_t Idle_Level; // Estado de la salida en reposo
} Advanced_OC_Config;
Función de Corte de Emergencia (Break)
La seguridad es primordial en el control de potencia. La entrada de Break permite forzar las salidas a un estado seguro predefinido de forma casi instantánea cuando se detecta una falla (como sobrecorriente o error en el reloj del sistema). Esta acción ocurre a nivel de hardware, garantizando tiempos de respuesta mínimos.
Diferencias entre Tipos de Temporizadores en STM32
- Avanzados (TIM1, TIM8): Soportan PWM con tiempo muerto, salidas complementarias y protección Break. Ideales para variadores de frecuencia.
- Propósito General (TIM2-TIM5): Ofrecen captura de entrada y comparación de salida estándar, pero carecen de funciones de seguridad para motores.
- Básicos (TIM6, TIM7): Carecen de pines externos. Se utilizan principalmente como base de tiempo para disparar el DAC o tareas simples de software.
Ejemplo Práctico: Configuración de PWM con Tiempo Muerto (HAL)
El siguiente código ilustra cómo inicializar el TIM1 para generar señales seguras para un controlador de potencia utilizando la capa de abstracción de hardware (HAL).
void Setup_Advanced_PWM(void)
{
TIM_HandleTypeDef timer_handler;
TIM_OC_InitTypeDef oc_config = {0};
TIM_BreakDeadTimeConfigTypeDef safety_config = {0};
// Configuración general del temporizador
timer_handler.Instance = TIM1;
timer_handler.Init.Prescaler = 71; // Reloj de 1MHz
timer_handler.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
timer_handler.Init.Period = 1000; // Frecuencia de 1kHz (centrado)
HAL_TIM_PWM_Init(&timer_handler);
// Parámetros del canal PWM
oc_config.OCMode = TIM_OCMODE_PWM1;
oc_config.Pulse = 450; // 45% de ciclo de trabajo
oc_config.OCPolarity = TIM_OCPOLARITY_HIGH;
oc_config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
oc_config.OCIdleState = TIM_OCIDLESTATE_RESET;
HAL_TIM_PWM_ConfigChannel(&timer_handler, &oc_config, TIM_CHANNEL_1);
// Inserción de tiempo muerto y seguridad
safety_config.DeadTime = 120; // Valor de retraso calculado
safety_config.BreakState = TIM_BREAK_ENABLE;
safety_config.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;
HAL_TIMEx_ConfigBreakDeadTime(&timer_handler, &safety_config);
// Activación de salidas
HAL_TIM_PWM_Start(&timer_handler, TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&timer_handler, TIM_CHANNEL_1);
}