Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 286 of 9364. Peripheral Interfacing and ControlFree lesson

Designing High-Resolution Quadrature Encoder Interfaces

Learners will configure timer encoder modes to decode phase-shifted signals from rotary encoders for precise motor position and velocity tracking.

In this lesson, you will learn how to leverage dedicated hardware timer modes to automatically track the position and velocity of a rotary encoder.

The Quadrature Challenge

A rotary encoder outputs two square waves, typically labeled Channel A and Channel B, which are 90 degrees out of phase. If you were to track these using basic GPIO interrupts, your CPU would be overwhelmed by the sheer frequency of edge transitions during high-speed rotation. Fortunately, most microcontrollers feature a hardware-level Encoder Interface Mode integrated directly into the timer peripheral.

Decoding Phase-Shifted Signals

Instead of manually checking which pin changed first, the timer hardware monitors both lines simultaneously. Because of the phase shift, the state of the two pins forms a 2-bit binary pattern (e.g., 00, 01, 11, 10).

When the hardware detects a transition, it uses this pattern to determine the direction of rotation automatically. If the sequence moves from 00 to 01, the motor is moving forward; if it moves from 00 to 10, it is moving backward. The timer’s internal counter increments or decrements based on this direction logic, effectively offloading the "math" from your CPU.

Configuring the Interface

To implement this, you configure the timer to look for edges on both signals, often referred to as "x4 decoding" because it counts every edge on both channels, providing four times the resolution per cycle of the encoder.

// Conceptual configuration for an Encoder Timer
void Setup_Quadrature_Interface(void) {
    // 1. Configure input pins as Alternate Functions (Mapping)
    // 2. Select Encoder Mode (e.g., TI1 and TI2 combined)
    Timer->CR1 |= ENCODER_MODE_X4; 
    
    // 3. Set the period (Maximum counts before overflow)
    Timer->ARR = 0xFFFF; 
    
    // 4. Start the timer
    Timer->CR1 |= TIMER_ENABLE;
}

By reading the Timer->CNT register, you obtain the current mechanical position relative to your starting point without needing to handle a single interrupt. To calculate velocity, you simply sample the difference in the counter value over a fixed time interval using a periodic interrupt.

Key Takeaway: By using hardware timer encoder modes, you offload the processing of phase-shifted signals from the CPU to the silicon, enabling high-resolution position tracking without the latency or overhead of software-based edge detection.