Determining the wheel position is an essential part of building a small car, and fortunately, the STM32 includes a hardware encoder . However, there are many inconveniences in its use. Let me explain them one by one:
1. Encoder Principle
What is orthogonality? If two signals are 90 degrees out of phase, they are said to be orthogonal. Because the two signals are 90 degrees out of phase, the direction can be determined by which signal came first, the distance traveled can be calculated based on the number of pulses in each signal and the circumference of the entire encoder wheel, and the speed can be calculated by adding a timer.
2. Why use an encoder?
As shown in the diagram above, due to the 90-degree phase difference between TI and T2, this phase difference indicates that the wheel has rotated by an angle. However, some might ask: since they are both pulses, why not use a regular I/O interrupt? Actually, if the wheel is rotating normally without any issues, there's no problem. But looking closely at the diagram, what if glitches appear? This is where we need to write algorithms in software to correct them. Therefore, we might think, wouldn't it be great if there were hardware that could handle this situation?
3. STM32 encoder
Using the same diagram as before, we can see that the STM32 hardware encoder is quite intelligent. When the T1 and T2 pulses are generated continuously, the counter increments or decrements by one. However, if a glitch or jitter occurs at a certain interface, the counter remains unchanged, meaning that the interface can tolerate jitter. In STM32, the encoder uses a timer interface. According to the datasheet, timers 1, 2, 3, 4, 5, and 8 have encoder functionality, while others do not. The encoder input signals TI1 and TI2 are filtered, and edge detection generates TI1FP1 and TI2FP2, which are connected to the encoder module. By configuring the encoder's operating mode, forward/reverse counting can be performed. If timer 3 is used, the corresponding pins are PA6 and PA7. According to the STM32 datasheet's encoder mode description, there are 6 combined counting modes, as shown in the table below.
Therefore, by selecting the appropriate timer method, we can determine which method to use to obtain the desired result. Using the STM32 encoder is also very simple; its basic steps are consistent with developing other STM32 components: turn on the clock, configure the interface, configure the mode, and enable interrupts if needed. For details, please refer to the following code (using TIM4, with pins GPIOA11 and GPIOA12):
4. Encoder interruption
Since encoders are timer-based, their interrupts are essentially the same as timer interrupts. A timer increments (or decrements) a number at regular intervals, generating an interrupt when the number reaches a preset value. An encoder, on the other hand, increments (or decrements) a number with each valid pulse, generating an interrupt when the preset value is reached. If the preset value is 1000, the difference between encoder and timer interrupts is that when the encoder rotates in reverse and reaches 999, an interrupt is generated; similarly, when the encoder rotates forward and reaches 0, an interrupt is also generated. Hardware-wise, these two interrupts are indistinguishable, leading to potential misjudgments.
5. Cases not considered by the STM32 encoder
Imagine the encoder's default value is 1000. What happens if we cause an interrupt by rotating the encoder forward, and then immediately reverse it? According to the above, this would generate two identical interrupts. Without proper algorithmic handling, it might be interpreted as two forward movements, which isn't actually the case. Therefore, we must determine the movement based on the direction (using the DIR register bits) or read the count register bit after the interrupt (checking if it's 999 or 0 to determine the current direction). Only if both the previous and current counts are positive will the distances be added together.
The specific interrupt handling function code is as follows:
6. The last question
What if there is no interrupt at the moment? Does that mean we can't get the precise position of the encoder?
It's actually just a very simple algorithm:
Record the number of interrupts each time, then record how many pulses have elapsed since the last interrupt, and add the two together.