2014-02-05 2:54 PM
I have just implementet a Low Speed Internal (LSI) oscillator calibration using a timer connected to the High Speed External (HSI) crystal. Right after I enabled the timer interrupt (and probably interrupt fires) I get redirected to the Default_Handler(). I can't see anything wrong with my code and hope someone could review it.
After enabling LSI clock and waiting for it to stabilize://Enable the Low Speed Internal oscillator.
RCC_LSICmd(ENABLE);
//Wait for LSI to stabilize.
while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
The LSI calibration function is called:
void LSI_Calibrate(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
//Enable Timer 5 clock.
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
//Register interrupt with Nested Vectored Interrupt Controller (NVIC).
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//Set Timer 5 prescaler.
TIM_PrescalerConfig(TIM5, 0, TIM_PSCReloadMode_Immediate);
//Connect LSI clock output to Timer 5 channel 4 input capture.
GPIO_PinRemapConfig(GPIO_Remap_TIM5CH4_LSI, ENABLE);
//Configure Timer 5 as input capture.
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV8;
TIM_ICInitStructure.TIM_ICFilter = 0;
TIM_ICInit(TIM5, &TIM_ICInitStructure);
//Reset Timer 5 counter.
timer5Counter = 0;
//Clear all interrupt flags.
TIM5->SR = 0;
//Enable channel 4.
TIM_CCxCmd(TIM5, TIM_Channel_4, TIM_CCx_Enable);
//Enable Timer 5 capture compare channel 4 interrupt.
TIM_ITConfig(TIM5, TIM_IT_CC4, ENABLE);
//Reset Timer 5.
TIM_SetCounter(TIM5, 0);
//Enable global interrupt.
__enable_irq();
//Enable Timer 5.
TIM_Cmd(TIM5, ENABLE);
//Wait for LSI calibration to finish.
while(timer5Counter < 2);
//Disable Timer 5 capture compare channel 4 interrupt.
TIM_ITConfig(TIM5, TIM_IT_CC4, DISABLE);
//Disable global interrupt.
__disable_irq();
//Disconnect LSI clock output to Timer 5 channel 4 input capture.
GPIO_PinRemapConfig(GPIO_Remap_TIM5CH4_LSI, DISABLE);
}
#interrupts
2014-02-05 4:24 PM
I don't see the handler.
Look at the handler, look at the linkage for the IRQHandler in the vector table, confirm it is there, and points to your handler. If using C++ consider if the name is mangled. Consider if you are using the right startup_stm32fxxx.sNot sure of your processor. Shouldn't really need to enable/disable global interrupt.2014-02-05 5:10 PM
I pressed ''open declaration'' on the ISR handler name and nothing happend. Rechecked the declarations and found out it was supposed to be TIM5_IRQHandler(), but mine was a copy paste mistake from my TIM1 (Advanced timer), which was then wrongly renamed to TIM5_CC_IRQHandler().
Thanks you clive1, again! =) I am enabling/disabling interrupt because this function is called at the very first of my program before all peripheral initialization. The interupts are enabled again before the main program loop.We’re moving the ST Community to a new platform to give you a better and more reliable community experience.