2014-02-05 02: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 04: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 05: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.