cancel
Showing results for 
Search instead for 
Did you mean: 

multiple TIM interrupts

klemen
Associate II
Posted on March 25, 2014 at 09:11

Hello,

I was hoping someone can steer me in the right direction regarding multiple TIM interrupts setup. I have configured two TIM's (TIM2 and TIM3) on STM32L151 and two IRQ handlers for both. One is giving interrupt every 1 ms (used for 16-bit millisecond counter) and the other every 50 ms (used for IWDG register reload). The TIM's setup:

// Timer setup (used for timer flag to send over serial)
void Init_TIM2(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
// Enable APB1 peripheral clock for TIM2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
// TIM update frequency = TIM clock / (P * Q), where Prescaler = P - 1, Period = Q - 1 
TIM_TimeBaseInitStruct.TIM_Prescaler = 32 - 1; 
TIM_TimeBaseInitStruct.TIM_Period = 1000 - 1; 
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; 
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
// APB1 prescaler = 1 (TIM clock = 32 MHz). The TIM update frequency is set to 32MHz/32kHz = 1000Hz = 1ms 
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); // Enable the TIM2 receive interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // Configure the TIM2 interrupts
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // Set the priority group of the TIM2 interrupts
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // Set the subpriority inside the group
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // Globally enable the TIM2 interrupts
NVIC_Init(&NVIC_InitStructure); // Init NVIC structure
// Enable TIM counter
TIM_Cmd(TIM2, ENABLE);
}
// Timer setup (used for watchdog interrupt)
void Init_TIM3(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
// Enable APB1 peripheral clock for TIM3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
// TIM update frequency = TIM clock / (P * Q), where Prescaler = P - 1, Period = Q - 1 
TIM_TimeBaseInitStruct.TIM_Prescaler = 160 - 1; 
TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1; 
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; 
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
// APB1 prescaler = 1 (TIM clock = 32 MHz). The TIM update frequency is set to 32MHz/1.6MHz = 20Hz = 50ms 
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); // Enable the TIM3 receive interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; // Configure the TIM3 interrupts
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // Set the priority group of the TIM3 interrupts
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // Set the subpriority inside the group
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // Globally enable the TIM3 interrupts
NVIC_Init(&NVIC_InitStructure); // Init NVIC structure
// Enable TIM counter
TIM_Cmd(TIM3, ENABLE); 
}

and the IRQ handlers:

// The interrupt request handler (IRQ) for all TIM2 interrupts
void TIM2_IRQHandler(void)
{
// Check interrupt status
if (TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
{
// Clear interrupt pending bits
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
// Increment 16-bit timer counter
if(timer_counter < 65535) {
timer_counter++;
}
// Reset timer counter before overflow (overflow would occur anyway)
else timer_counter = 0;
}
}
// The interrupt request handler (IRQ) for all TIM3 interrupts
void TIM3_IRQHandler(void)
{
// Check interrupt status
if (TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)
{
// Clear interrupt pending bits
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
// Reload the IWDG counter
IWDG_ReloadCounter(); 
}
}

The problem is that the code above seems not to generate the interrupt and the watchdog does not get reloaded, thus the uC resets every 1500 ms (IWDG setup). If I put the ''IWDG_ReloadCounter()'' function in the TIM2 IRQ, the code works properly. Could you please help me configure the interrupts and point me to some literature/example on how to correctly configure multiple interrupts? Thank you very much and best regards, K
1 REPLY 1
klemen
Associate II
Posted on March 25, 2014 at 10:36

Hello,

I solved my issue by using one interrupt for both tasks (maybe this is even better?):

// The interrupt request handler (IRQ) for all TIM2 interrupts
void TIM2_IRQHandler(void)
{
// Check interrupt status
if (TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
{
// Clear interrupt pending bits
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
// Increment 16-bit timer counter
if(timer_counter < 
65535
) {
timer_counter++;
}
// Reset timer counter before overflow (overflow would occur anyway)
else 
timer_counter
= 
0
;
// Increment the IWDG iterator
IWDG_iterator++;
// Reload the IWDG each 50 ms
if(IWDG_iterator >= 50) { 
// Reload the IWDG counter
IWDG_ReloadCounter();
// Reset the IWDG iterator
IWDG_iterator = 0;
}
}
}

But, still I would like to know what is the problem with the code in the previous post. Thank you and best regards, K