Este é o código para o timer no meu projeto no 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");
}
}
}
E depois de executar a timerReset()
função no meio do meu programa, a interrupção começa não apenas alguns segundos depois, mas quase imediatamente. Tentei alguns outros temporizadores para verificar se não há nenhum problema de hardware, mas não, não é.
microcontroller
c
stm32
interrupts
timer
m0drzew
fonte
fonte
Respostas:
Eu me deparei com isso com um STM32F105. As funções da Biblioteca de periféricos padrão STM32F1xx são um pouco diferentes das que você está usando, mas a ideia deve ser a mesma.
A emissão da
TIM_TimeBaseInit()
função fez com que o sinalizador TIM_SR_UIF fosse definido. Ainda não voltei para descobrir o porquê. Depois que esse bit é definido, a interrupção será acionada assim que for ativada.Para consertar, depois de ligar
TIM_TimeBaseInit()
, liguei imediatamenteTIM_ClearITPendingBit()
. Então eu habilitaria a interrupção comTIM_ITConfig()
. Isso resolveu o problema.Minha rotina completa de inicialização é assim:
fonte
__HAL_TIM_CLEAR_FLAG(&htim6, TIM_SR_UIF);
Como tive um problema semelhante e não encontrei respostas, estou compartilhando minha experiência na esperança de ajudar outras pessoas.
Acredito que, no seu caso, definir o URS (Update Request Source) antes de inicializar o timer também resolve o problema.
No meu caso, estou usando os drivers de camada baixa, portanto, um código de exemplo seria:
O problema é que eu estava usando as funções
LL_TIM_SetPrescaler(TIM16, 7999)
eLL_TIM_SetAutoReload(TIM16, 2999)
para configurar a base de tempo e descobri que, ao usar essas funções, os valores não estavam sendo atualizados, então tive que gerar um evento para atualizar os valores usandoLL_TIM_GenerateEvent_UPDATE(TIM16)
.Você pode limpar o sinalizador de evento usando
LL_TIM_ClearFlag_UPDATE(TIM16)
antes de ativar a interrupção ou usarLL_TIM_SetUpdateSource(TIM16, LL_TIM_UPDATESOURCE_COUNTER)
antes de gerar o evento.fonte
Eu tive um problema semelhante no mod One Pulse e encontrei a solução para a biblioteca HAL. Quando eu controlei sinalizadores de timer na função "TIM2_IRQHandler", vi "captura comparar sinalizador 1" está definido. Então eu limpei "capture compare flag 1". Mas desta vez vi "captura comparar bandeira 2" está definido. Portanto, limpei todos os sinalizadores de comparação (de 1 a 4) na minha função "TIM2_IRQHandler" usando os códigos a seguir.
fonte
Mesmo problema com TIM_TimeBaseInit () e STM32F0xx. A última string desta função:
Ele define o evento de atualização no Event Generation Register. É por isso que coloquei o cheque no manipulador de IRQ:
fonte