This repository provides an MPLAB® X project for a Charlieplexing implementation using the Configurable Logic Block (CLB) and Timer0 (TMR0) peripherals for controlling six LEDs. Using this multiplexing technique, only three pins are needed to drive the LEDs.
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.
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

-
6 x LEDs of the same color
-
3 x 100 Ohm resistors
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 example demonstrates the capabilities of the CLB, a Core Independent Peripheral (CIP), that can generate the waveforms that drives the six LEDs connected in a Charlieplexing configuration.
The electric schematic is shown in the figure below. The LEDs have the property that they conduct current only in one direction and they act as open circuit when connected in the opposite direction. By connecting two LEDs in parallel and in oposite directions, only two pins are needed to control them one by one.

The Charlieplexing implementation assumes that only one LED is driven at a given time. To obtain that using the schematic above, two of the drive pins are used to control an LED (one pin is set as logic HIGH and the other as logic LOW) and the third one is used in tri-state, meaning that the output buffer of the pin is disabled and it has a High-Z impedence. Without using the tri-state buffer, two LEDs would be driven in any situation when tring to turn ON only one.
The following tables shows how the drive pins and the tri-state buffers of the pins must be configured to control each LED. The tri-state buffer is enabled for the DRIVE output that is not used for controlling the LED.
| DRIVE1 | DRIVE2 | DRIVE3 | |
|---|---|---|---|
| LED0 | LOW | - | HIGH |
| LED1 | HIGH | - | LOW |
| LED2 | LOW | HIGH | - |
| LED3 | HIGH | LOW | - |
| LED4 | - | LOW | HIGH |
| LED5 | - | HIGH | LOW |
| Tri-state1 | Tri-state2 | Tri-state3 | |
|---|---|---|---|
| LED0 | OFF | ON | OFF |
| LED1 | OFF | ON | OFF |
| LED2 | OFF | OFF | ON |
| LED3 | OFF | OFF | ON |
| LED4 | ON | OFF | OFF |
| LED5 | ON | OFF | OFF |
Even if only one LED can be driven at a certain moment, it is possible to create the impression that many LEDs are driven at the same time by turning them ON one by one at a sufficiently high frequency. This implementation is done in hardware using the CLB peripheral and it is shown in the figure below.

The internal hardware counter is used to switch between the six LEDs. The frequency at which the LED number is updated is configured using the TMR0 peripheral. For this implementation, the update frequency for all of the six LEDs is 60 Hz, resulting in a 6*60=360 Hz for the timer output frequency.
The TRISC0-2 outputs are used to enable or disable the tri-state buffer of the driving pins (logic '0' - output is disabled, logic '1' - output is enabled) using the NOR gates based on the table above. Note that the tri-state control using the CLB peripheral is available only on the PORTC pins on this device.
There are six software inputs used to configure the state of each LED (logic '0' - OFF, logic '1' - ON). For each of the six cases, only one of the drive outputs is logic '1'. When the state for a certain LED is selected by the hardware counter by making the corresponding output high, the AND gate between the counter state and the software input of that LED verifies if the corresponding drive output have to be made logic '1' (the LED is ON) or it remains logic '0' (the LED is OFF). After all six LEDs are verified, the counter is reset and the process is resumed. CLBSWIN0-5 are used for configuring the LEDs to allow the usage of the CLB1_SWIN_Write8() function to write the LEDs mask in software.
The following masks are defined in the main program to control the LEDs. The user can simply use these masks and the WRITE_LEDS(leds) macro define to modify the LEDs state.
#define LEDS_OFF (0x00)
#define LED0 (0x01 << 0)
#define LED1 (0x01 << 1)
#define LED2 (0x01 << 2)
#define LED3 (0x01 << 3)
#define LED4 (0x01 << 4)
#define LED5 (0x01 << 5)
#define WRITE_LEDS(leds) do { CLB1_SWIN_Write8(leds); } while(0)
Some predifined LEDs patterns are created in the example program and are sequentially called in the main loop with a 500 ms delay to demonstrate the functionality. For example, the following pattern is used to turn ON the LEDs one by one.
const uint8_t ledPattern1[13] = {LEDS_OFF, LED0, LED1, LED2, LED3, LED4, LED5, LED4, LED3, LED2, LED1, LED0, LEDS_OFF};
The following peripheral and clock configurations are set up using MPLAB Code Configurator (MCC) Melody for the PIC16F13276:
-
Configurations Bits:
-
Clock Control:
-
CLB Synthesizer Library:
-
CLB1:
-
TMR0:
-
CRC:
- Auto-configured by the CLB
-
Pin Grid View:
The demo below shows how the patters created in the main program control the six LEDs.
Note: The demo is at 2x speed.

This example demonstrates the capabilities of the CLB, a CIP that can generate the waveforms that controls six LEDs connected in a Charlieplexing configuration.
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:
a. Right click the project and click Properties.
b. Click the arrow under the Connected Hardware Tool.
c. 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.







