z. Up to 9 channel 32-bit arbitrary frequency PWM generation with PIC32MXF128B output compare units

Driving a servo motor usually requires the use of a low frequency PWM signal generator. PIC32MX2xxFxxxB have 5 such generators within OCx (output compare units, where x = {1, …, 5}) and PIC32MZ2048ECyxxx have 9 such generators. Though PIC32MX2xxFxxxB and PIC32MZ2048ECyxxx firmwares v2.9.1 or later have an inbuilt support for 8-channel low frequency signal generation, OCs are much more accurate because everything is done in hardware. It suffices to simply set the correct values in timer 2/3 and OCx unit registers. The latter can even be done from a VB.NET program with direct memory write instructions, like this:

PIC.MemWrite(C32T2CON, 0) ' Set 32-bit mode and disable timer 2/3

PIC.MemWrite(C32T3CON, 0) ' Set 32-bit mode and disable timer 2/3

PIC.MemWrite(C32OC1CON, 0) ' OC1CON = 0

PIC.MemWrite(C32TMR2, 0) 'clear timer 2/3

PIC.MemWrite(C32RPB15R, 5) ' RB15 = OC1

PIC.MemWrite(C32TRISB Or C32REG_SET, &H200) ' let RB15 be output

PIC.MemWrite(C32T2CON, &H8) ' Set 32-bit mode and disable timer 2/3

PIC.MemWrite(C32PR3, &H400) ‘ PR3:PR2 register pair contains 32-bit period*

PIC.MemWrite(C32PR2, &H0)

PIC.MemWrite(C32OC1R, 0) ' OC1R = 0

PIC.MemWrite(C32OC1RS, &H800000) ' OC1RS = &h1000

PIC.MemWrite(C32T2CON Or C32REG_SET, &H8000) ' Enable timer 2/3

PIC.MemWrite(C32OC1CON, &H26) ' OC1CON = &H26

PIC.MemWrite(C32OC1CON + C32REG_SET, &H8000) ' Enable(OC1)

*NOTE: Register pair PR3:PR2 contains an impulse period time derived from the peripheral clock. System clock vs. peripheral clock ratio can be up to 1:8, but 1:1 ratio is usually the most useful, because of the huge 32-bit span of the register pair. PR3 register contains upper 16 bits and PR2 register contains lower 16 bits.

The sample code on the left demonstrates a very low frequency generation that can be visually observed on PB15 output (Q8 output on K8055 board with PIC32MX250F128B adapter and PIC32MZ2048ECH100 to Velleman K8055-1 experiment board adapter). 20 MHz FOX924 external oscillator was used for the system clock. System clock vs. peripheral cock ratio was set to 1:1. K8055-1 board with PIC32MX250F128B adapter was used for testing, but the functionality is also available with the PIC32MX2xxFxxxB basic circuits and PIC32MZ2048ECx100 - 100-pin PIM basic USB circuit.

32-bit and 64-bit samples that also work on PIC32MZ microcontrollers are available from Downloads section: PIC32MX250F128B signal frequency and phase measurement example with source code (x64).zip. The sample just shows how a very low frequency signal can be generated in PIC32 hardware. The program code above can be run by pressing “Generate PWM in RB0” button. Copy the code to your application and load values from program variables to PR3:PR2 to vary the period time (frequency). Also load pulse length to 32-bit OC1RS register.

ALSO READ:

- Basic circuit for PIC32MX2xxFxxxB to work over USB with a 20 MHz external oscillator

- Basic circuit for PIC32MX2xxFxxxB to work over USB with an 8.000000 MHz crystal resonator

- Wireless data transfer and signal frequency and phase measurement with PIC32MX250F128B: standalone or on adapter to K8055-1 or K8055N-2 experiment board

- 8-channel low frequency PWM generator in PIC32 firmware