Skip to main content
Explorer
February 11, 2025
Solved

Encoder on STM32U083 gives interrupts too late while counting up

  • February 11, 2025
  • 2 replies
  • 772 views

In my project, I am using a low power timer (LPTIM1) to handle input from a quadrature encoder. I have set the timer up in CubeMX as follows:

- IN1 and IN2 are used for the hardware inputs (this is always true; I cannot set this up).

- Channel 1 and 2 are active in output compare mode with no external pins, only interrupts.

- Clock polarity is set to both edges.

- Sample time (glitch filter) is set to 8 transitions.

- The LSI (32 kHz) is selected as its input clock.

At boot, I set the value of both channels to be the current timer values plus and minus 2 respectively. This should mean I get an interrupt when the encoder is rotated to the next mechanically stable position.

On any interrupt, I reset the values of the channel registers to be the new value of the CNT register plus and minus 2.

 

What I expect to see, is a single interrupt for any mechanical click on the encoder, where I can use the CNT register to figure out if the rotation was up or down.

What I see instead, is that this works properly for down rotations (where the counter decreases in value), but for up rotations it needs to be turned 2 mechanical clicks. At that point, the value of the timer has correctly increased by 4.

In a debugger, I have paused the system after one click and inspected the hardware registers. This can be seen in this screen shot:

wijnen_0-1739290473348.jpeg

As can be seen, CCR1 is 1 and CCR2 is 5. This was set up when CNT was 3. I have rotated the encoder and CNT is correctly increased to 5. However, no interrupt triggered and ISR.CC2IF is zero, meaning it does not detect a match.

From this state, after another click on the encoder, CNT increased to 7, CCR1 and CCR2 were unchanged, but then an interrupt is triggered.

I want to know why this happens, and more importantly, how I can detect every click on the encoder in both directions.

    This topic has been closed for replies.
    Best answer by TDK

    On the LPTIM, when CCRx=5, interrupt happens when CNT changes from 5 to 6. So if CNT=3 and you want an interrupt when CNT changes to 5, set CCRx=4.

    Per the reference manual:

    TDK_0-1739296616203.png

    At least that's how I interpret it, and it matches the observation.

    2 replies

    TDKAnswer
    Super User
    February 11, 2025

    On the LPTIM, when CCRx=5, interrupt happens when CNT changes from 5 to 6. So if CNT=3 and you want an interrupt when CNT changes to 5, set CCRx=4.

    Per the reference manual:

    TDK_0-1739296616203.png

    At least that's how I interpret it, and it matches the observation.

    wijnenAuthor
    Explorer
    February 13, 2025

    Thanks, that seems to do the trick indeed.

    Originally I thought it was completely broken when I tried that, but that was because I did not wait for the changes to CCR* to be picked up by the LPTIM before checking if the counter was still within the bounds. But now that I fixed that as well, everything works perfectly. The reference menual could be improved though; this figure is in the PWM output section. Which makes sense as I'm using the output compare register, but I'm definitely not doing PWM.

    Anyway, thanks a lot for the help.

    Super User
    February 13, 2025

    It's likely written in the other sections as well. The RM is quite comprehensive.