STM32: Timer interrupt works immediately

I ran into this with an STM32F105. The STM32F1xx Standard Peripheral Library functions are a bit different than what you are using, but the idea should be the same.

Issuing the TIM_TimeBaseInit() function caused the TIM_SR_UIF flag to become set. I haven't gone back yet to figure out why. Once this bit is set, the interrupt will trigger as soon as it is enabled.

To fix it, after calling TIM_TimeBaseInit(), I immediately called TIM_ClearITPendingBit(). Then I would enable the interrupt with TIM_ITConfig(). This fixed the problem.

My complete initialization routine looks like this:

// Enable the peripheral clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

// Configure the timebase
TIM_TimeBaseInitStructure.TIM_Prescaler = 1;
TIM_TimeBaseInitStructure.TIM_Period = 35999;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStructure);

// That last function caused the UIF flag to get set. Clear it.
TIM_ClearITPendingBit(TIM5, TIM_IT_Update);

// Configure so that the interrupt flag is only set upon overflow
TIM_UpdateRequestConfig(TIM5, TIM_UpdateSource_Regular);

// Enable the TIM5 Update Interrupt type
TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);

If debugging, remember that by default the peripherals won't stop on core halt, so the timers will keep triggering the interrupt while you're halted. I also had a nice headache back time ago, until I discovered the bits for freezing peripherals in debug mode.

You can enable it at start of main like this:

void main(void){

   __HAL_DBGMCU_FREEZE_TIM1();    // Enable Timer1 Freeze on Debug

   HAL_Init();

   // blah
   // blah rest of the main code
   // blah
}

You have all the definitions at the start of stm32f4xx_hal.h