STM32 alcanza el punto de interrupción cuando TIM1 preescala 2

0

Estoy generando una señal PWM en STM32F103 usando TIM1. El código de inicio de la base de tiempo es:

timebase_prescale = 1;
timebase_reload = 3000;


TIM_TimeBaseInitTypeDef timebase;
timebase.TIM_Prescaler = timebase_prescale - 1;
timebase.TIM_CounterMode = TIM_CounterMode_Up;
timebase.TIM_Period = timebase_reload;
timebase.TIM_ClockDivision = TIM_CKD_DIV1;
timebase.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &timebase);

TIM_CtrlPWMOutputs(TIM1, ENABLE);

Con algún código adicional para configurar el canal 1 y un pin de E / S obtengo una señal de salida de 24 kHz. Perfecto.

Al configurar

timebase_prescale = 2;

En cambio, obtengo 12 kHz como se esperaba, pero tan pronto como uso algo > 2 el procesador se detiene y OpenOCD informa

target halted due to breakpoint, current mode: Thread

¿Qué está mal?

EDIT:

Después de la configuración de la base de tiempo anterior, los pines se inicializan y se inicia el PWM:

void multipwm_setup_channel(int channel)
{
    TIM_OCInitTypeDef config;

    config.TIM_OCMode = TIM_OCMode_PWM1;  // or 2 ???
    config.TIM_OutputState = TIM_OutputState_Enable;
    config.TIM_OutputNState = TIM_OutputNState_Enable;
    config.TIM_Pulse = timebase_reload / 4;  // initial compare value

    config.TIM_OCPolarity = TIM_OCPolarity_High;
    config.TIM_OCNPolarity = TIM_OCNPolarity_High;

    config.TIM_OCIdleState = TIM_OCIdleState_Reset;
    config.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

    switch (channel)
    {
        case 1:
            gpio_config(GPIOA, GPIO_Pin_8, GPIO_Mode_AF_PP, GPIO_Speed_10MHz);
            gpio_config(GPIOB, GPIO_Pin_13, GPIO_Mode_AF_PP, GPIO_Speed_10MHz);
            TIM_OC1Init(TIM1, &config);
            TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
            break;

        case 2:
            gpio_config(GPIOA, GPIO_Pin_9, GPIO_Mode_AF_PP, GPIO_Speed_10MHz);
            gpio_config(GPIOB, GPIO_Pin_14, GPIO_Mode_AF_PP, GPIO_Speed_10MHz);
            TIM_OC2Init(TIM1, &config);
            break;

....

    }
}

La secuencia inicial completa es

    multipwm_setup();  // enables timer 1 clock
    multipwm_set_frequency(30000);
    multipwm_setup_channel(1);
    multipwm_setup_channel(2);
    multipwm_start();  // calls TIM_Cmd(TIM1, ENABLE);

El reloj funciona a 72MHz; configuración predeterminada de algún código de inicio del sistema estándar que no escribí yo mismo. Los 30000 Hz son lo que realmente quería (calcula timebase_prescale como 1), pero probé 50 Hz solo para ver si mi código funcionaría y descubrí que falló con valores de preescala más altos.

TIM_CtrlPWMOutputs() debe llamarse antes de TIM_TimeBaseInit() . Ahora puedo usar el valor de prescaler que necesite.

Pero todavía no siempre funciona! Añadir TIM_Cmd(TIM1, DISABLE); y volver a habilitar el temporizador más tarde parece resolver el problema, ¿por ahora?

    

1 respuesta

0

El problema inmediato que puedo ver, sin entrar en ningún cálculo es con esta línea

 TIM_CtrlPWMOutputs(TIM1, ENABLE);

Como mencioné en el comentario, ¡no necesitas eso! ¿Conoces esta función en particular de acuerdo con Std_Peripheral_Library que habilita MOE (salida principal) en BDTR (registro de interrupción y tiempo muerto)? y si es su intención utilizarlo, ¡debe configurarlo en consecuencia!

¡Lo que básicamente estás haciendo es encender el temporizador para un propósito especial y reconfigurarlo para PWM y encender el contador del temporizador (función TIM_Cmd) nuevamente! Creo que esto está causando el conflicto. La solución es simplemente eliminar la línea anterior de su código.

No estoy seguro de lo que hace su función "multipwm_set_frequency". Pero en general es muy fácil configurar el temporizador para la frecuencia PWM deseada.

Frecuencia de PWM deseada = (TIM_CLK / PrescalerValue-1) / (Periodo-1);

En general, es preciso calcular PrescalerValue a partir del valor de system_core_clock. Luego puede usar, valor de pulso como Período / 4 para un ciclo de trabajo del 25% (como lo ha hecho), Período / 2 para un ciclo de trabajo del 50% y así sucesivamente ...

    
respondido por el charansai

Lea otras preguntas en las etiquetas