2016-02-01 01:26 AM
I want to generate an interrupt after 2 seconds and I am running at 32 MHz. However, my interrupt is issued as soon as I enable the interrupt. What am I doing wrong?
void testTimer4(EventCallback_t timerInterruptCallback)
{
timerInterruptCallback_ = timerInterruptCallback;
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
TIM4->PSC = 976;
TIM4->ARR = 65505;
TIM4->CNT = 0;
TIM4->SR &= (~TIM_SR_UIF);
TIM4->DIER |= TIM_DIER_UIE;
HAL_NVIC_EnableIRQ(TIM4_IRQn);
TIM4->CR1 |= TIM_CR1_CEN;
}
void TIM4_IRQHandler(void)
{
TIM4->SR &= (~TIM_SR_UIF);
HAL_NVIC_DisableIRQ(TIM4_IRQn);
TIM4->DIER &= (~TIM_DIER_UIE);
TIM4->CR1 &= (~TIM_CR1_CEN);
RCC->APB1ENR &= (~RCC_APB1ENR_TIM4EN);
(void)timerInterruptCallback_((uint32_t)TIMER_4_EXPIRED, 0);
}
2016-02-01 01:36 AM
You change prescaler, in configuration stage generate software uptade then clear all flags.
Your code looks very strange.
TIM4->SR &= (~TIM_SR_UIF);
TIM4->DIER |= TIM_DIER_UIE;
Don't use RMW editing on SR registers. You don,t check if coresponding interrupt is enabled.
sign ~ should be before ( etc.
Mixing HAL and reg style is *****.
2016-02-01 02:45 AM
Hi arnold_w,
Check this discussion about the “Timer interrupt after start�?:
.You be inspired there from my recommendations.
-Hannibal-
2016-02-01 03:56 AM
Thank you for your replies. So, the problem was that I forgot to update the prescalar after it was set. The following code works great.
void testTimer4(EventCallback_t timerInterruptCallback)
{ timerInterruptCallback_ = timerInterruptCallback; RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; TIM4->PSC = 976; TIM4->EGR = TIM_EGR_UG; // Generate an update event to reload the Prescaler TIM4->ARR = 65505; TIM4->CNT = 0; TIM4->SR &= (~TIM_SR_UIF); TIM4->DIER |= TIM_DIER_UIE; HAL_NVIC_EnableIRQ(TIM4_IRQn); TIM4->CR1 |= TIM_CR1_CEN; } void TIM4_IRQHandler(void) { TIM4->SR &= (~TIM_SR_UIF); HAL_NVIC_DisableIRQ(TIM4_IRQn); TIM4->DIER &= (~TIM_DIER_UIE); TIM4->CR1 &= (~TIM_CR1_CEN); RCC->APB1ENR &= (~RCC_APB1ENR_TIM4EN); (void)timerInterruptCallback_((uint32_t)TIMER_4_EXPIRED, 0); }