Este es el código para el temporizador en mi proyecto en STM32F429:
//timer initialization
void timerInit()
{
uwPrescalerValue2 = (uint32_t) ((SystemCoreClock / 2) / 100000) - 1;
RS485Timer.Instance = TIM5;
RS485Timer.Init.Period = 67400000; // high value to notice interrupt even without debugging
RS485Timer.Init.Prescaler = 400000;
RS485Timer.Init.ClockDivision = 0;
RS485Timer.Init.CounterMode = TIM_COUNTERMODE_UP;
HAL_TIM_Base_Init(&RS485Timer);
}
void timerReset()
{
HAL_TIM_Base_Stop_IT(&RS485Timer);
HAL_TIM_Base_DeInit(&RS485Timer);
HAL_TIM_Base_Init(&RS485Timer);
HAL_TIM_Base_Start_IT(&RS485Timer);
printf("%d timer reset\n", countereset);
countereset++;
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* TIMx Peripheral clock enable */
__TIM5_CLK_ENABLE();
/*##-2- Configure the NVIC for TIMx #########################################*/
/* Set the TIMx priority */
HAL_NVIC_SetPriority(TIM5_IRQn, 7, 1);
/* Enable the TIMx global Interrupt */
HAL_NVIC_EnableIRQ(TIM5_IRQn);
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim)
{
__TIM5_FORCE_RESET();
__TIM5_RELEASE_RESET();
HAL_NVIC_DisableIRQ(TIM5_IRQn);
}
void TIM5_IRQHandler(void)
{
if (__HAL_TIM_GET_FLAG(&RS485Timer, TIM_FLAG_UPDATE) != RESET) //In case other interrupts are also running
{
if (__HAL_TIM_GET_ITSTATUS(&RS485Timer, TIM_IT_UPDATE) != RESET)
{
__HAL_TIM_CLEAR_FLAG(&RS485Timer, TIM_FLAG_UPDATE);
HAL_TIM_IRQHandler(&RS485Timer);
printf("timer interrupt\n");
}
}
}
Y después de ejecutar la timerReset()
función en el medio de mi programa, la interrupción comienza no pocos segundos después, sino casi de inmediato. Intenté algunos otros temporizadores para verificar si no hay problemas de hardware, pero no, no lo es.
microcontroller
c
stm32
interrupts
timer
m0drzew
fuente
fuente
Respuestas:
Me encontré con esto con un STM32F105. Las funciones de la Biblioteca de periféricos estándar STM32F1xx son un poco diferentes de lo que está utilizando, pero la idea debería ser la misma.
La emisión de la
TIM_TimeBaseInit()
función provocó que se estableciera el indicador TIM_SR_UIF. Todavía no he regresado para entender por qué. Una vez que se establece este bit, la interrupción se activará tan pronto como se habilite.Para solucionarlo, después de llamar
TIM_TimeBaseInit()
, llamé de inmediatoTIM_ClearITPendingBit()
. Entonces permitiría la interrupción conTIM_ITConfig()
. Esto solucionó el problema.Mi rutina de inicialización completa se ve así:
fuente
__HAL_TIM_CLEAR_FLAG(&htim6, TIM_SR_UIF);
Como tenía un problema similar y no había encontrado respuestas, comparto mi experiencia con la esperanza de ayudar a otras personas.
Creo que en su caso, configurar el URS (Fuente de solicitud de actualización) antes de inicializar el temporizador también resuelve el problema.
En mi caso, estoy usando los controladores de capa baja, por lo que un código de ejemplo sería:
El problema es que estaba usando las funciones
LL_TIM_SetPrescaler(TIM16, 7999)
yLL_TIM_SetAutoReload(TIM16, 2999)
para configurar la base de tiempo, y descubrí que al usar estas funciones, los valores no se actualizaban, así que tuve que generar un evento para actualizar los valores usandoLL_TIM_GenerateEvent_UPDATE(TIM16)
.Luego, puede borrar el indicador de evento usando
LL_TIM_ClearFlag_UPDATE(TIM16)
antes de habilitar la interrupción, o usarLL_TIM_SetUpdateSource(TIM16, LL_TIM_UPDATESOURCE_COUNTER)
antes de generar el evento.fuente
Tuve un problema similar en One Pulse mod y encontré una solución para la biblioteca HAL. Cuando controlé los indicadores del temporizador en la función "TIM2_IRQHandler", vi que se estableció "capturar comparar indicador 1". Así que borré "captura, compara y marca 1". Pero esta vez vi "Capturar comparar bandera 2" está configurado. Así que borré todos los indicadores de comparación (del 1 al 4) en mi función "TIM2_IRQHandler" usando los siguientes códigos.
fuente
Mismo problema con TIM_TimeBaseInit () y STM32F0xx. La última cadena de esta función:
Establece el evento de actualización en Event Generation Register. Es por eso que puse cheque en el controlador IRQ:
fuente