cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F746NG : Output Compare Interrupt triggering at random

APete
Associate II

I am trying to use Timer Output Compare on STM32F746NG with the following code:

void TIM1_CC_IRQHandler(void)
{
	volatile uint32_t a = TIM1->CNT;
 
	printf("DUMMY\r\n");
}
 
void timer_start(void)
{
	TIM_HandleTypeDef htim1;
	  TIM_OC_InitTypeDef tim1_ch1;
 
	__HAL_RCC_TIM1_CLK_ENABLE();
	htim1.Instance = TIM1;
	htim1.Init.Prescaler = 7;
	htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
	htim1.Init.Period = 107;
	htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
	htim1.Init.RepetitionCounter = 0;
	htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
	while (HAL_TIM_OC_Init(&htim1) != HAL_OK);
 
	tim1_ch1.OCMode = TIM_OCMODE_PWM1;
	tim1_ch1.OCPolarity = TIM_OCNPOLARITY_HIGH;
	tim1_ch1.OCFastMode = TIM_OCFAST_DISABLE;
	tim1_ch1.Pulse = 50;
 
	__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_CC1);
	HAL_NVIC_SetPriority(TIM1_CC_IRQn, 5, 0);
	HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
 
	HAL_TIM_OC_ConfigChannel(&htim1, &tim1_ch1, TIM_CHANNEL_1);
	HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
}
 
 
int main(void)
{
 
  HAL_Init();
  SystemClock_Config();
 
  timer_start();
 
  while (1)
  {
  }
}

I am putting a breakpoint in the IRQHandler printf to see if the ISR is executed. It executes. When I change tim1_ch1.Pulse to 5000 from 50, the ISR is still entered. I was expecting that only when the Pulse Value (CCR1 in this case) matched with the Counter Value (TIM1->CNT) the Compare Interrupt would be triggered. I am also getting random values for the variable a inside the ISR, when I am observing it through Watch.

Will Output Compare Interrupt trigger in such random manner ? I am not able to figure where I go wrong ! Any help will be deeply appreciated. Thanks

1 ACCEPTED SOLUTION

Accepted Solutions

> .Pulse to 5000 from 50, the ISR is still entered. I was expecting that only when the Pulse

> Value (CCR1 in this case) matched with the Counter Value (TIM1->CNT) the Compare

> Interrupt would be triggered

No, this is an exception (and yes it's surprising to the unaware):

0690X000006DTAaQAO.png 

The CNT register content appears to be random as your interrupt service routine (ISR) executes waaaaay longer than the time between consecutive interrupts is.

Bottom line: NEVER use printf() and kin in an ISR.

JW

View solution in original post

4 REPLIES 4
S.Ma
Principal
  • Is the timer overflows and runs continuously?
  • Is the timer stopped when a breakpoint occurs?
  • Do you (or HAL) clear the pending interrupt flag when in the compare interrupt?
  • Is the interrupt still working when the next output compare fires? (too long interrupt)
  • Do you update the compare register values in the interrupt?

> .Pulse to 5000 from 50, the ISR is still entered. I was expecting that only when the Pulse

> Value (CCR1 in this case) matched with the Counter Value (TIM1->CNT) the Compare

> Interrupt would be triggered

No, this is an exception (and yes it's surprising to the unaware):

0690X000006DTAaQAO.png 

The CNT register content appears to be random as your interrupt service routine (ISR) executes waaaaay longer than the time between consecutive interrupts is.

Bottom line: NEVER use printf() and kin in an ISR.

JW

APete
Associate II

The timer over flows and runs continuously.

This code that I have presented here was simplified to reproduce the problem. The original code has the required instructions to clear the interrupt flags. Still the problem repeats.

APete
Associate II

Thank you jan for passing the reference.

Probably a bad choice, but I used the printf as a sample instruction to hold as a breakpoint and to observe the value of the variable through the Debugger . This was a simplified code I wrote out to demonstrate the problem. Didnt want to clutter the post with all the unnecessary details from the original code.

Once again Thank You Very Much for pointing out the issue.