Generación y cálculo de tablas de búsqueda para seno y coseno

La generación y cálculo de tablas de búsqueda (LUT) para funciones trigonométricas implica varios pasos clave:

  1. Definición de la resolución (tamaño de la tabla)

  • Para un número de micropasos deseado N, el tamaño típico de la tabla es N (aunque puede ser N+1 para facilitar la conexión circular).
  • Por ejemplo, si se requieren 256 micropasos, se define TABLE_SIZE = 256.
  1. Cálculo del incremento angular

El paso angular entre elementos de la tabla se determina con:

[ \Delta\theta = \frac{2\pi}{\text{TABLE_SIZE}} ]

  1. Cálculo de valores de seno y coseno en punto flotante

Para cada índice \(i = 0,1,\dots,\text{TABLE_SIZE}-1\), se calcula:

[ \theta_i = i \times \Delta\theta, \quad \text{sinTbl}[i] = \sin(\theta_i), \quad \text{cosTbl}[i] = \cos(\theta_i). ]

Ejemplo en pseudocódigo:

for (int i = 0; i < TABLE_SIZE; i++) {
    float angle = 2.0f * M_PI * i / TABLE_SIZE;
    sinTbl[i] = sinf(angle);
    cosTbl[i] = cosf(angle);
}

  1. Conversión a valores de ciclo útil (duty cycle) para PWM

En microcontroladores, los ciclos útiles son enteros; por lo tanto, se mapea el rango −1 a +1 al intervalo 0 a PWM_MAX:

[ \text{CCR_value} = \bigl(\text{wave} + 1.0\bigr)\times \frac{\text{PWM_MAX}}{2} ]

Donde:

  • wave representa los valores de sinTbl[i] o cosTbl[i];
  • PWM_MAX es el valor de carga automática del temporizador (ARR), como 1000, 4095 o 65535.
uint16_t duty = (uint16_t)((sinTbl[i] + 1.0f) * 0.5f * PWM_MAX);

  1. Optimización de tipo de datos y almacenamiento

  • Tabla en punto flotante: Si el MCU soporta operaciones en punto flotante, se pueden almacenar directamente como float.
  • Tabla en punto fijo: Para ahorrar memoria flash, se multiplica cada valor por un factor fijo (por ejemplo, 32767) y se guarda como int16_t:

[ \text{sinQ}[i] = \text{round}\bigl(\sin(\theta_i)\times 32767\bigr) ]

Posteriormente, durante la ejecución, se convierte mediante desplazamiento o multiplicación al ciclo útil.

  1. Conexión circular y interpolación

  • La primera y última entrada suelen representar el mismo ángulo (0° o 360°), por lo que se puede almacenar solo una copia de las primeras N entradas.
  • Para mayor precisión, se puede aplicar interpolación lineal en tiempo de ejecución, aunque en la mayoría de casos basta con acceso directo a la tabla.
  1. Ejemplo completo

// Declaración global o estática
#define TABLE_SIZE 256
#define PWM_MAX    4095
int16_t sinTblQ[TABLE_SIZE];
int16_t cosTblQ[TABLE_SIZE];

// Inicialización de la tabla de búsqueda
void InitLUT(void) {
    for (int i = 0; i < TABLE_SIZE; i++) {
        float angle = 2.0f * M_PI * i / TABLE_SIZE;
        sinTblQ[i] = (int16_t)(sinf(angle) * 32767);
        cosTblQ[i] = (int16_t)(cosf(angle) * 32767);
    }
}

// Función para obtener el ciclo útil
uint16_t GetPWMDuty(int idx, int16_t *tblQ) {
    return (uint16_t)(( (tblQ[idx] + 32767) / 65535.0f ) * PWM_MAX);
}

// Uso en salida:
uint16_t dutyA = GetPWMDuty(idx, sinTblQ); // Ciclo útil para fase A
uint16_t dutyB = GetPWMDuty(idx, cosTblQ); // Ciclo útil para fase B


Estos valores se escriben en los registros de comparación de los temporizadores (CCR) para controlar los puentes H del driver A4950, generando un vector de campo magnético correspondiente al ángulo θ = idx×(2π/TABLE_SIZE).

De esta forma, se puede generar dinámicamente una tabla de seno y coseno para cualquier nivel de细分 (microstepping) y mapearla a los ciclos útiles del temporizador para control preciso de motores paso a paso.

Recomendaciones prácticas

Selección de hardware:

  • Utilizar temporizadores avanzados de STM32 (TIM1 o TIM8), que ofrecen:
  • 4 salidas PWM independientes, o
  • 2 salidas complementarias (útil para drivers con control de dead time).
  • Capacidad suficiente para controlar los 4 puentes necesarios para un motor paso a paso bipolar.

Implementación de sfotware:

  1. Creación de la tabla de búsqueda
  • Generar una tabla estándar de seno/coseno (punto flotante o punto fijo).
  • Se puede usar una sola tabla con desplazamiento de fase para generar dos fases.
  1. Control de salida PWM
  • Usar DMA o bucles de interrupción para escribir los ciclos útiles (dutyA+, dutyA-, dutyB+, dutyB-) en los registros CCR del temporizador:``` TIMx->CCR1 = dutyA_plus; TIMx->CCR2 = dutyA_minus; TIMx->CCR3 = dutyB_plus; TIMx->CCR4 = dutyB_minus;
3. **Control del índice de paso**


- Actualizar el índice de forma sencilla para rotar la fase (ej. dirección de avance):```
idx = (idx ± 1) % TABLE_SIZE;


  • El resto del proceso se maneja automáticamente mediante DMA, garantizando actualizaciones estables y eficientes.

Esta metodología permite implementar sistemas de control de motores paso a paso con alta precisión, gran细分 y bajo ruido, especialmente adecuados para aplicaciones de microstepping.

Etiquetas: STM32 TIM1 TIM8 PWM lookup table

Publicado el 9-7 01:18