2014-03-25 01:11 AM
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
2014-03-25 02:36 AM
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