Showing results for 
Search instead for 
Did you mean: 

Timer compare function interrupt not triggered sometimes

Associate II

Hi everyone, I meet a problem and I'm not sure it's MCU issue or I program not proper.

I meet this issue both on the STM8 and STM32 MCUs.

I enable TIM_2 Ch1 as input to capture the signal and TIM_2 Ch2 as output to do the compare function.


void init_TIM_2
  RCC.APB1ENR.bit.TIM2EN = 1;
  TIM2.CCMR1.bit.Inmode.IC1S = 1;
  TIM2.CCMR1.bit.Inmode.IC1PSC = 0;
  TIM2.CCER.bit.CC1P = 0;
  TIM2.CCER.bit.CC1E = 1;
  TIM2.CCMR1.bit.Outmode.OC2S = 0;
  TIM2.CCER.bit.CC2E = 1;
  TIM2.DIER.bit.CC2IE = 1;


 Also I enable the global interrupt with the NVIC module. So the interrupt is working.

And what I do in the interrupt just set a new compare value and toggle an GPIO pin.


void TIM2_ISR(void)
  if (TIM2.SR.bit.CC2IF)
    int p = TIM2_CCR;
    int new_val = 0;
    // Calculate a new compare value
    // Toggle the GPIO pin
    TIM2.CCR = p + new_val;

    TIM2.SR.bit.CC2IF = 0;


I found it will miss the compare value sometime.

I trace the CCR value and timer counter value of TIM2, the CCR value should be greater than the counter value in normal case. But I found it's not triggered the ISR and the counter just exceed the CCR value sometimes.

If I program not proper, please have some advise for me. Thank you!

The actual data trace list as below:

TIM2 CCR valueTIM2 counter valueNotes
2173556321740124The counter val > CCR and no interrupt event

@waclawek.jan It really helps me a lot. I thought what I set is only 1 bit not a whole bits of register. But I trace the assembly code and it really did the LDR->BIC->STR and it cause the other interrupt flags clear either.


Many thanks.

Chief II

The reasons why for register accesses the bit-fields are harmful and useless:

  1. If one omits the volatile qualifier, the code is just broken.
  2. With the volatile qualifier every bit or bit-field access leads to a separate set of RMW instructions, which leads to a generally inefficient and for some uses (interrupt clearing) again broken code.