cancel
Showing results for 
Search instead for 
Did you mean: 

TIM2 Output Compare is generating unwanted interrupts every ARR period

GWood.1
Associate II

Please note: what I am describing is my experimentation to try to figure out how all this works. Yes, there are likely things you wouldn't do in a real life situation, but I want to understand all the edge cases.

Also note, I am not using a HAL or library (I am actually using Rust, but that shouldn't matter), so all the details I describe directly relate to registers. Please don't suggest how to "fix" my issue by using a HAL or library.

And finally, all help is GREATLY appreciated, I've been banging my head against the wall for days on this now!

Here goes...

  • Timer is the 32bit TIM2
  • It is set up so each TIM2 CNT increment = 1uS
  • But I'm only using 16 bits (again, for test purposes), so ARR = 65535
  • I manually increment CCR1 by 110 in my TIM2 interrupt handler on each valid interrupt
  • I filter the interrupt handler on SR.CC1IF = 1
  • The OC mode is "frozen", I am not using the microcontroller to control the output pin for me

Test goal: To toggle an output pin in my TIM2 interrupt handler using Output Compare mode. For test purposes, I am not linking the output stages to a pin. My pin toggling is being done in my interrupt handler.

IF CC1IE = 0, no interrupts are generated at all - as expected

If CC1IE = 1, I get the expected interrupts when CNT=CCR1. I then manually increment CCR1, using my own function to wrap around the value of ARR. I then toggle a GPIO pin for viewing on a 'scope.

My issue is that I also get interrupts every "ARR" period.

I know this, because if I don't manually wrap CCR1 around ARR, and just let CCR1 keeps on increasing skyward, my Output Compare is effectively disabled (at least until it wraps around the 32bit max value after 71 minutes), and so during this time the desired interrupts don't fire. BUT, I DO STILL GET INTERRUPTS, not every 110uS, but every 65ms (the value of ARR). I assume these must be firing when CNT overflows ARR.

This is extremely undesirable, as these extra interrupts every 65ms will cause incorrect pulse widths among my 110uS pulses

I tried setting/clearing both CR1.UDIS and CR1.URS, hoping in vain one of these may disable the undesired interrupts, but no setting makes a difference. (I may have misinterpreted these settings, the reference manual is a not super clear)

What am I missing?

  • Is it impossible to filter out these apparent ARR overflow related interrupts? This is the IDEAL solution
  • Should I use TIM1, which appears to have an extra CC specific interrupt handler? A workaround
  • I can probably use the Output stages, as intended, and it may workaround the problem, but I'd prefer to know what is going on and how to fix it.

1 ACCEPTED SOLUTION

Accepted Solutions

Your probably complaining about the documented behaviour of CC when CCRx>ARR.

JW

View solution in original post

5 REPLIES 5

Your probably complaining about the documented behaviour of CC when CCRx>ARR.

JW

Thanks for that.

I did see another post about that documented "feature" (which kinda looks like it was undefined behaviour that was later inserted into the reference manual!)

Upon re reading the reference manual, it simply says you get an interrupt when CCRx>ARR, which could be interpreted in 3 ways....

1. An interrupt is fired once when ​CCRx first exceeds ARR, in which case the interrupt would fire (in my case) once every 71 minutes,

2. The interrupt fires every time CCRx is modified and is > ARR, in which case my interrupts would fire at their normal rate once every 110uS, which makes a mockery of CCRx being out of range of ARR.

3. The interrupt fires on every CNT increment when CCRx > ARR, in which case I would be getting pulses every 1uS, provided the processor can keep up.

None of these CCRx > ARR theories fit my observations of an interrupt every 65ms (ARR period).

There were some additional extra points in the "gotcha" article, such as setting all other channels to Input Capture, since they could be generating interrupts. This sounded promising, but made no difference.

None of the 3.

The documentation quite clearly says:

When the contents of TIMx_CCR1 are greater than the contents of TIMx_ARR, the CC1IF bit goes high on the counter overflow [...]

i.e. when CNT == ARR (once in 65ms, since you set ARR=65536).

JW

GWood.1
Associate II

Ah! It is all so clear when read properly! Maybe I shouldn't write code at 1:30am!

That sets my mind at rest... that when my non-experimental code is running, I don't get extra interrupts.

Thanks again for your help and patience

Greg

Greg,

> Maybe I shouldn't write code at 1:30am!

This ought to be taught in the schools... 🙂 Glad you got it working.

Jan