AnsweredAssumed Answered

multiple TIM interrupts

Question asked by p.klemen on Mar 25, 2014
Latest reply on Mar 25, 2014 by p.klemen
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

Outcomes