0
\$\begingroup\$

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);
    }
}
\$\endgroup\$
  • \$\begingroup\$ I'm not very familiar with the HAL, but I'm missing that you tell the timer which interrupt you want. \$\endgroup\$ – Arsenal Nov 19 '18 at 8:59
2
\$\begingroup\$

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;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.