2011-11-20 02:09 AM
Hi Forum!
First time I'm trying to do something with interrupts, and I get a HardFault Exception :) I'm using the IAR Workbench 6.3 with the STM32DISOVERY_VL - EvalBoard. Here's the main-function code (completely copied from the StdPeriph-Lib, ''/TIM/OC Inactive'' is the example's path) : /* Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 2000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Output Compare Active Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM2, ENABLE); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* Set PC.06, PC.07, PC.08 and PC.09 pins */ GPIO_SetBits(GPIOC, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); while (1) {} And here's the ISR in an extern file (''stm32f10x_it'') : void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) { /* Clear TIM2 Capture Compare1 interrupt pending bit*/ TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); /* PC.06 turnoff after 1000 ms */ GPIO_ResetBits(GPIOC, GPIO_Pin_6); } else if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) { /* Clear TIM2 Capture Compare2 interrupt pending bit*/ TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); /* PC.07 turnoff after 500 ms */ GPIO_ResetBits(GPIOC, GPIO_Pin_7); } else if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET) { /* Clear TIM2 Capture Compare3 interrupt pending bit*/ TIM_ClearITPendingBit(TIM2, TIM_IT_CC3); /* PC.08 turnoff after 250 ms */ GPIO_ResetBits(GPIOC, GPIO_Pin_8); } else { /* Clear TIM2 Capture Compare4 interrupt pending bit*/ TIM_ClearITPendingBit(TIM2, TIM_IT_CC4); /* PC.09 turnoff after 125 ms */ GPIO_ResetBits(GPIOC, GPIO_Pin_9); } } Everytime I run throught the code statement by statement, the cursor disappears at the while-loop at the end of main(). Afterwards I press the stop-button, the debugger jumps into the HardFault_Handler()-routine and get stuck in the empty while loop. I also looked at the disassembly before jumping into the while loop of main() and I noticed the question marks -> ??main_0: 0x80004c8: 0xe7fe Hope you have enough info, and I hope you can help me with this. Thank you in advance! Chris2011-11-20 03:25 AM
Hi there,
Try something simple first, this works for me: I used KEIL though......but It think IAR will follow the same trend void TIMER2(void) { TIM_InternalClockConfig(TIM2); /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 0x1B58; TIM_TimeBaseStructure.TIM_Prescaler = 0x00; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV4; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); /* TIM enable counter */ TIM_Cmd(TIM2, ENABLE); } .......void TIM2_IRQHandler(void)
{ static u8 t=0;if (TIM_GetITStatus(TIM2, TIM_IT_Update))
{ TIM_ClearITPendingBit(TIM2, TIM_IT_Update); if(t){ t=0; } else{ t=1; LED_1_OFF; LED_0_OFF; }} } Tx Ben
2011-11-20 07:28 AM
Well it's conceivable that you haven't set the NVIC and vectors up correctly. Have you confirmed if it even enters the interrupt routine.
If you want to understand the reason for a Hard Fault, you should be examining the stacked processor condition to determine the PC and registers at the failure point. Try something like Joseph Yiu's Hard Fault Handler, in place of the while(1); loop everyone is so fond of.2011-11-20 09:30 AM