HardFOC driver
PCA9685 Driver¶
A C++20 driver for the NXP PCA9685 16-channel, 12-bit PWM controller. It sets the PWM frequency, drives each channel by duty cycle or by on/off tick, and controls sleep and the output stage, on any MCU with I2C.
The driver has no platform code. You give it a small class that brings an I2C bus up and reads and writes register bytes; it does the rest: the prescaler calculation, the sleep sequence the PRE_SCALE register needs, channel frames, retries and error flags.
- Outputs
- 16 channels, 12-bit (4096 steps) each, with a programmable on time and off time
- PWM frequency
- 24 Hz to 1526 Hz, one frequency for all channels (25 MHz internal oscillator, or EXTCLK up to 50 MHz)
- Host interface
- I2C up to 1 MHz (Fast-mode Plus); 7-bit address
0x40to0x7Ffrom pins A0 to A5 - Output stage
- Totem pole (25 mA sink, 10 mA source at 5 V) or open drain; OE pin, active low
- Supply
- 2.3 V to 5.5 V, inputs and outputs 5.5 V tolerant; −40 °C to +85 °C
- Package
- TSSOP28, HVQFN28
What you get¶
- One object per chip.
PCA9685<YourBus>takes the bus and the 7-bit address; several chips share one bus. See API guide. - Frequency in hertz.
SetPwmFreq()computes PRE_SCALE and runs the sleep / write / wake sequence the chip requires. See PWM timing. - Channels by duty or by tick.
SetDuty(),SetPwm()with a phase offset, full on, full off and all channels at once. See API guide. - Errors you can inspect. Every call returns
bool; a bitmask ofErrorflags says why. Register accesses retry with an optional delay. See API guide. - Zero-overhead portability. The port is a CRTP class with three methods: no virtual calls, no heap, no RTOS dependency. See Porting.
- Tested without hardware. Host unit tests run the driver against a model of the chip's registers. See Testing and CI.
Where to go next¶
-
Wire the chip, write the port, centre a servo in about 15 lines.
-
Pins, addresses, bus settings, output stage and power.
-
The three layers and what each one owns.
-
Initialise, set the frequency, drive outputs and handle errors, task by task.
-
Implement the I2C interface for your MCU.
-
Every class and member, generated from the headers.