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.
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;
}