# Problem with interrupt-based timer on STM32F411

I was following this online tutorial and cannot get the interrupt-based timer to work. I know the timer is running because if I uncomment the five lines in the main loop, I get a nice square wave output. But with those lines commented out, the timer interrupt is not firing and I cannot figure out why. Can someone suggest what I'm doing wrong?

#include "stm32f4xx_hal.h"

void SysTick_Handler(void)
{
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
}

static TIM_HandleTypeDef s_TimerInstance = { .Instance = TIM2 };

void InitializeTimer()
{
__TIM2_CLK_ENABLE();
s_TimerInstance.Init.Prescaler = 160;
s_TimerInstance.Init.CounterMode = TIM_COUNTERMODE_UP;
s_TimerInstance.Init.Period = 100;
s_TimerInstance.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
s_TimerInstance.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&s_TimerInstance);
HAL_TIM_Base_Start(&s_TimerInstance);
}

void InitializeLED()
{
__GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = LD2_Pin;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStructure);
}

void TIM2_IRQHandler()
{
HAL_TIM_IRQHandler(&s_TimerInstance);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
}

int main(void)
{
HAL_Init();
InitializeLED();
InitializeTimer();

HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);

for (;;)
{
//        int timerValue = __HAL_TIM_GET_COUNTER(&s_TimerInstance);
//        if (timerValue == 50)
//            HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
//        if (timerValue == 100)
//            HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
}
}

• I'm not very familiar with the HAL, but I'm missing that you tell the timer which interrupt you want. – Arsenal Nov 19 '18 at 8:59

Looks like the UIE bit in TIM2->DIER is not enabled. There must be some HAL function to do it, I don't know. I would not recommend using HAL for timing stuff anyway, there are issues with its accuracy.

Starting a timer is just a few lines of code.

void InitializeTimer(void) {
__TIM2_CLK_ENABLE();
TIM2->PSC = 160;             /* Set prescaler value */
TIM2->EGR = TIM_EGR_UG;      /* Update prescaler */
TIM2->ARR = 100;             /* Set timer period */
TIM2->DIER = TIM_DIER_UIE;   /* Enable interrupt generation on timer overflow */
TIM2->CR1 = TIM_CR1_CEN;     /* Start counting */
}

void TIM2_IRQHandler()
{
/* Clear interrupt flag first. It cannot be the last instruction in an interrupt handler. */
TIM2->SR = 0;
LD2_GPIO_Port->ODR ^= LD2_Pin;
}