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?