This repository provides an MPLAB® X project that implements a quadrature decoder circuit using the configurable logic block (CLB) peripheral.
The CLB peripheral is a collection of logic elements that can be programmed to perform a wide variety of digital logic functions. The logic function may be completely combinatorial, sequential, or a combination of the two, enabling users to incorporate hardware-based custom logic into their applications.
Quadrature signals are the standard output waveforms of incremental encoders that come with motors. They provide information about motor direction and shaft position. There are two types of encoders — linear and rotary — and each can have two types of measurement: absolute and incremental. There are also different technologies used for encoders: magnetic, optical, inductive, capacitive, and laser.
The main categories of encoders are absolute and incremental. A rotary absolute encoder outputs a unique code for each position of the motor's shaft. If the power of this encoder is lost and the shaft is rotated, the encoder can return the correct position of the shaft. The rotary incremental encoder generates pulses while the shaft is rotated. If any pulse is missed, then the shaft position cannot be determined correctly anymore. This application will use a rotary incremental encoder to show how to decode quadrature signals.
The following image highlights the clockwise (CW) and counterclockwise (CCW) conditions on the quadrature signals A and B. When signal A leads signal B (on rising or falling edge), it will be a clockwise detection, otherwise, when signal B leads signal A (on rising or falling edge), it will be a counterclockwise detection.
More details and code examples on the PIC16F13276 can be found at the following links:
- MPLAB® X IDE v6.30 or newer or MPLAB® Tools for VS Code®
- MPLAB® XC8 v3.10 or newer
- PIC16F1xxxx_DFP v1.29.444 or newer
-
The PIC16F13276 Curiosity Nano Development board is used as a test platform:

-
Oscilloscope/Logic analyzer
Note: The setup can be made using a rotary encoder or a motor equipped with an encoder. The current example focuses on a setup with rotary encoder.
To program the Curiosity Nano board with this MPLAB X project, follow the steps provided in the How to Program the Curiosity Nano Board chapter.
This application showcases the capabilities of the CLB peripheral by creating a logic circuit that decodes the waveforms from a rotary encoder. Each time a clockwise or counterclockwise condition is detected, one clock cycle pulse is generated on the corresponding output line (clockwise or counterclockwise). The output signals are routed as clock sources for Timer0 (TMR0) and Timer1 (TMR1), the timers being used to count the ticks. The total numbers of encoder increments is obtained by subtracting the values read from timers. By using timers as counters to store the rotation information, the CPU does not need to monitor the decoder signal and can simply calculate the total rotation since its last check when a new rotation value is needed. The following image presents the decoder circuit implementation:
The phase signals from the rotary encoder have glitches when transitioning, so a debouncing circuit is used to avoid false detections. The debouncing circuit is presented in the figure below:
To detect a clockwise turn of the rotary encoder, the phase A signal has to lead the phase B signal either on a rising or falling edge. There are two scenarios:
- Rising edge detected on phase B while phase A is high
- Falling edge detected on phase B while phase A is low
To detect a counterclowise turn of the rotary encoder, the phase B signal has to lead the phase A signal either on a rising or falling edge. There are two scenarios:
- Rising edge detected on phase A while phase B is high
- Falling edge detected on phase A while phase B is low
To implement edge detection for the phase signals the following edge detector circuits have been used:
The following peripheral and clock configurations are set up using MPLAB® Code Configurator (MCC) Melody for the PIC16F13276:
-
Configuration Bits:
-
Clock Control:
-
Interrupt Manager:
-
CLB Synthesizer Library:
-
CLB1:
-
CRC:
- Auto-configured by CLB
-
TMR0:
-
TMR1:
-
TMR2:
- Timer Enable: Enabled
- Control Mode: Roll over pulse
- Clock Source: LFINTOSC
- Prescaler: 1:32
- Postscaler: 1:16
- Timer Period (s): 2
- TMR Interrupt Enable: Enabled

Note: The TMR2 module is used to create a 2 second interrupt.
-
UART2:
-
EUSART2:
-
Pin Grid View and Pins:
The following pin configurations must be made for this project:
| Pin | Configuration | Function |
|---|---|---|
| RC7 | Input | Encoder phase A |
| RC6 | Input | Encoder phase B |
| RC0 | Output | CW detection |
| RC1 | Output | CCW detection |
| RD6 | Output | EUSART2 TX2 |
| RD7 | Input | EUSART2 RX2 |
The setup for the demo is presented in the diagram below.
The total number of pulses detected over two seconds is printed on the serial terminal.
The figure below presents a logic analyzer capture that contains the rotary encoder waveforms and the detected pulses.

Note: Follow the steps in the How to use MPLAB® Data Visualizer section to set up the Data Visualizer so that it can correctly show the text messages through UART2.
This application showcases how to create a quadrature decoder circuit that can detect and count clockwise and counterclockwise pulses on rising and falling edges of the quadrature signals using the CLB peripheral.
This section illustrates how to use the MPLAB® X Data Visualizer. This can be applied to any other projects.
-
Open the software terminal in MPLAB® X IDE. Click on the Data Visualizer button.

-
Select the Input Source corresponding to the PIC16F13276 in the right side.
-
Identify the COMx port corresponding to the PIC16F13276 Curiosity Nano board and select it in the Connections tab in the left-side menu.
-
Set the specific Baud Rate, in this case 115200.
-
Press the Start streaming COMx button. The text messages will appear in the Terminal tab.

This chapter demonstrates how to use the MPLAB X IDE to program a PIC® device with an Example_Project.X. This is applicable to other projects.
-
Connect the board to the PC.
-
Open the
Example_Project.Xproject in MPLAB X IDE. -
Set the
Example_Project.Xproject as main project.
Right click the project in the Projects tab and click Set as Main Project.
-
Clean and build the
Example_Project.Xproject.
Right click theExample_Project.Xproject and select Clean and Build.
-
Select PICxxxxx Curiosity Nano in the Connected Hardware Tool section of the project settings:
Right click the project and click Properties.
Click the arrow under the Connected Hardware Tool.
Select PICxxxxx Curiosity Nano (click the SN), click Apply and then click OK:
-
Program the project to the board.
Right click the project and click Make and Program Device.




















