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);
}
}
-
\$\begingroup\$ I'm not very familiar with the HAL, but I'm missing that you tell the timer which interrupt you want. \$\endgroup\$Arsenal– Arsenal2018年11月19日 08:59:28 +00:00Commented Nov 19, 2018 at 8:59
1 Answer 1
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;
}
-
1\$\begingroup\$ Here is an explanation on why you may not clear the UIF flag last stackoverflow.com/questions/50105120/… \$\endgroup\$Freggar– Freggar2020年03月06日 17:25:31 +00:00Commented Mar 6, 2020 at 17:25