Re: 12F1572 Unable to achieve 100% PWM and still use phase delay feature 12F1571 12F157x
Thanks for the detailed reply.
I also tried that as a solution, however this is just one of the waveforms I need to produce, and the others cannot use an inverted 3rd channel. Flipping the channel generates glitches that the project can't tolerate.
So, after pounding my head against the data sheet for a while longer, I accidentally ran across the correct incantations to get the offset mechanism to work.
This setup actually does what I wanted, which is to run the PWM registers as offsets of each other. Phase A leading, then Phase B, then Phase C.
// Setup up the PWM machinery
PWM3CLKCON = PWM2CLKCON = PWM1CLKCON = 0b01110000; // ~4KHz
PWM3INTE = PWM2INTE = PWM1INTE = 0; // No Interrupts.
PWM3OF = PWM2OF = PWM1OF = 0;
PWM3CON = PWM2CON = PWM1CON = 0b01000000; // Module disabled, output enabled
PWM3PH = PWM2PH = PWM1PH = 0; // phase is always 0
// PWM setup for synchronized operation on all 3 PWM modules
PWM1LDCON = 0b10000000; // Load armed, no trigger
PWM2LDCON = 0b11000001; // Load armed, trigger on PWM1
PWM3LDCON = 0b11000010; // Load armed, trigger on PWM2
PWM1OFCON = 0; // independent, NO_match, match_incrementing
PWM2OFCON = 0b01000001; // One-shot slave, matching PWM1
PWM3OFCON = 0b01000010; // One-shot slave, matching PWM2
PWMEN = 0b111; // Enable all three modules at the same time to maintain sync
PWM3PR = PWM2PR = PWM1PR = PERIOD_LENGTH-1; // PWM Period
Then when changing phase values:
PWMEN = 0; // Critical to disable and renable the PWMs (otherwise the output is undefined)
PWM1OF = PWM1DC = PhaseA;
PWM2OF = PWM2DC = PhaseB;
PWM3DC = PhaseC;
PWMEN = 0b111; // Must be more than one instruction between disable and enable
I had gone down this path before but not had success, the scope trace was a mess of random transitions. I went back to one of those examples and noticed that the very glitchy scope trace would occasionally show the right waveform. Disabling and re-enabling the PWM block cured that and the waveform is clean. None of that is documented in the data sheet, of course. Also, you can't disable, and re-enable the PWM block in successive instructions. Doesn't work.