2020-09-25 02:20 PM
Hello all,
I want to disable the timer interrupt in the IRQ Handler and then enable again in the main loop. However the interrupt is triggered nearly immediately after I re-enable the interrupt (setting the UIE bit). I attached my code below. If I disable and enable the counter instead of just the interrupt then the code runs correctly. Why is that? I have tried to set the TIM_CR1_URS but no avail.
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 3333;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM2_Init();
HAL_TIM_Base_Start_IT(&htim2);
uint16_t c;
while (1)
{
if(int_count == 1)
{
int_count = 0;
HAL_GPIO_WritePin(GPIOA, TX_pin, 0);
__HAL_TIM_SET_COUNTER(&htim2, 0);
__HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE);
}
c = 0xFFFF;
while(c)
{
c--;
}
}
}
void TIM2_IRQHandler(void)
{
if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(&htim2, TIM_IT_UPDATE) != RESET)
{
__HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_UPDATE);
if(int_count == 0)
{
__HAL_TIM_DISABLE_IT(&htim2, TIM_IT_UPDATE);
HAL_GPIO_WritePin(GPIOA, TX_pin, 1);
int_count = 1;
}
}
}
return;
}
P/S: Side question: when I debugged the code, I notice that when I clear the interrupt flag with __HAL_TIM_CLEAR_FLAG, even though the code says the flag is cleared but I still see bit UIF set when looking at the timer register. Does anyone know why?
Solved! Go to Solution.
2020-09-25 03:12 PM
The update interrupt will fire immediately after enabled in HAL_TIM_Base_Start_IT unless you clear it first. Note that if ARR=0, it'll get set immediately. So you need to set ARR, then clear the flag, then start the timer.
When debugging, the timer is still running unless you have timers disabled during debug so it gets set immediately again.
Mixing HAL calls with your own IRQ handler doesn't seem smart. You should call HAL_TIM_IRQHandler instead. Or just ditch HAL.
2020-09-25 03:12 PM
The update interrupt will fire immediately after enabled in HAL_TIM_Base_Start_IT unless you clear it first. Note that if ARR=0, it'll get set immediately. So you need to set ARR, then clear the flag, then start the timer.
When debugging, the timer is still running unless you have timers disabled during debug so it gets set immediately again.
Mixing HAL calls with your own IRQ handler doesn't seem smart. You should call HAL_TIM_IRQHandler instead. Or just ditch HAL.
2020-09-25 03:33 PM
"Mixing HAL calls with your own IRQ handler doesn't seem smart."
Why is that? I want to use HAL but the HAL interrupt handlers are too long so I decided to write my own.
Anw, adding __HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_UPDATE); before __HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE); solves the problem.
2020-09-25 03:38 PM