cancel
Showing results for 
Search instead for 
Did you mean: 

TIM2 Interrupt -> HardFault Exception

shadowrunner92
Associate II
Posted on November 20, 2011 at 11:09

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!

Chris
3 REPLIES 3
benbb
Associate II
Posted on November 20, 2011 at 12:25

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

Posted on November 20, 2011 at 16:28

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
shadowrunner92
Associate II
Posted on November 20, 2011 at 18:30

Thank you for your answers! 🙂

In the meanwhile I tried the simple program from the first answer, but it didn't change anything.

After that, I run the code using the EWARM-template from the StdPheriphLib, now it works! (Unfortunatly the project folder is now crowded with a lot of files, I don't even now what most of them are for.)

For sure I forgot some certain library files where the InterruptVectors where in. With my old project I couldn't even set a breakpoint into the ISR, seeming the compiler couldn't even reach the interrupt-function. Now everything works fine!

Regards

Chris