29.5.1 Generating Phase-Shifted Waveforms

Figure 29-10 shows an application example for generating phase-shifted PWM waveforms. In this example, PWM1 generates a waveform and the rising edge of this pulse is the trigger input to the PTG module. When the trigger from PWM1 is received, the PTG module waits on PTG Timer 0 using the PTGCTRL(0b1000) command, inserting a programmable delay and then outputting a PCI signal to PWM2. This signal is the synchronization source for PWM2, which is configured to output a single cycle with the same period and duty cycle as PWM1. As PWM2 is repeatedly triggered by the PTG, it outputs a phase-shifted version of PWM1, with the phase shift determined by the PTG Timer 0 delay.

Figure 29-10. Phase-Shifted Waveform Example Application

Generating Phase-Shifted Waveforms shows code for generating a phase-shifted waveform.

Generating Phase-Shifted Waveforms


#include "xc.h"
#include "ptg.h"     //Contains Examples 2-1, 2-2, and 2-3

void IO_initialize() {
    _PCI12R = 167;   //Connect PCI 12 to PTG trigger 26
    _TRISD2 = 0;     //PWM1H will be output on RD2
    _TRISD0 = 0;     //PWM2H will be output on RD0
}

void PWM1_initialize() {
    
    PG1CONbits.CLKSEL = 1; //Main PWM clock (undivided/unscaled) used for PWM2
    PG1CONbits.MSTEN = 1; //Broadcast status of update bit/EOC to other generators 
    PG1IOCONbits.PENH = 1; //PWM generator 1 controls PWM1H pin
    PG1EVTbits.ADTR2EN1 = 1; //PGA1TRIGA match controls PWM1 ADC Trigger 2
    
    PG1PER = 8000;         //Period 1ms for a 8MHz PWM clock
    PG1DC = 4000;          //50% duty cycle
    PG1PHASE = 0;          //0 phase offset
    PG1TRIGA = 0x0000;     //PWM ADC trigger 2 will happen at start of cycle
    
    PG1CONbits.ON = 1;     //Enable PWM Generator 1
}

void PWM2_initialize() {
    PG2CONbits.CLKSEL = 1; //Main PWM clock (undivided/unscaled) used for PWM2
    PG2CONbits.TRGMOD = 1; //PWM generator is re-triggerable
    PG2CONbits.SOCS = 0b1111; //PCI sync used for start of cycle
    PG2IOCONbits.PENH = 1; //PWM generator 2 controls PWM2H pin
    PG2PER = 8000; //Period 1ms for a 8MHz PWM clock
    PG2DC = 4000; //50% duty cycle
    PG2PHASE = 0; //0 phase offset
    PG2SPCIbits.PSS = 0b01100; //PCI12 as PWM2 sync source
    PG2CONbits.ON = 1; //Enable PWM Generator 2
}

void PTG_initialize() {
    PTGT0LIM = 1000; //0.125ms T0 delay
    PTGQUE0bits.STEP0 = PTGWHI(0); //Wait for high-to-low edge on trigger from PWM1
    PTGQUE0bits.STEP1 = PTGCTRL(t0Wait); //Wait on T0
    PTGQUE0bits.STEP2 = PTGTRIG(26); //Trigger PWM2
    PTGQUE0bits.STEP3 = PTGJMP(0); //Restart sequence
    PTGCONbits.ON = 1; //Enable PTG
    PTGCONbits.PTGSTRT = 1; //Start executing commands
}

void clocks_initialize() {
    //Assuming 8MHz FRC is default clock selection:
    CLK5CONbits.ON = 1;     //8MHz for the Main PWM clock
    CLK10CONbits.ON = 1;    //8MHz for the PTG clock
}

int main(void) {
    clocks_initialize();
    IO_initialize();
    PWM1_initialize();
    PWM2_initialize();
    PTG_initialize();
    
    while (1);
    
    return 0;
}