17.5.1.1 Six-Step Commutation – PWM Scheme 1
In this PWM scheme, only two switches are active at any given time. Of the two active phases, one high-side and one low-side switch are controlled with their phase’s corresponding PWM waveform, as shown in Figure 17-40.
Since only one switch needs to be driven at a time on a given phase, Independent PWM Output mode is used. The output override feature is then used to suppress the unused output. A three-phase scheme is implemented using PWM Generator 1 (PG1) configured as host and the other two PWM Generators (PG2 and PG3) configured as clients. PG1 is self-triggered, whereas PG2 and PG3 are triggered from PG1’s Start-of-Cycle (SOC). Enabling PG1 will start the system in a synchronized fashion.
Configuration Summary:
- Independent Edge PWM mode
- Independent Output mode
- Master Period and Duty Cycle Used
- Override State is drive low
Six-Step PWM Scheme 1 Code
//#include <stdint.h>
//For delay function
#define FCY 8000000 //CPU frequency in Hz
#include "libpic30.h"
uint16_t state = 0;
#define H_ACTIVE_L_LOW 0x001C1000
//PGxIOCONbits.PMOD = 0b01 -- Independent output mode
//PGxIOCONbits.PENH = 1 -- PWM Generator x controls PWMxH output pin
//PGxIOCONbits.PENL = 1 -- PWM Generator x controls PWMxL output pin
//PGxIOCONbits.OVRENH = 0 -- PWMxH output not overridden
//PGxIOCONbits.OVRENL = 1 -- PWMxL output overridden
//PGxIOCONbits.OVRDAT = 0b00 -- Override data for PWMxH/L (only L uses it) is 0
//PGxIOCONbits.OSYNC = 0b00 -- User output overrides are synchronized to next start of cycle
#define H_LOW_L_LOW 0x001C3000
//PGxIOCONbits.PMOD = 0b01 -- Independent output mode
//PGxIOCONbits.PENH = 1 -- PWM Generator x controls PWMxH output pin
//PGxIOCONbits.PENL = 1 -- PWM Generator x controls PWMxL output pin
//PGxIOCONbits.OVRENH = 1 -- PWMxH output overridden
//PGxIOCONbits.OVRENL = 1 -- PWMxL output overridden
//PGxIOCONbits.OVRDAT = 0b00 -- Override data for PWMxH/L is 0
//PGxIOCONbits.OSYNC = 0b00 -- User output overrides are synchronized to next start of cycle
#define H_LOW_L_ACTIVE 0x001C2000
//PGxIOCONbits.PMOD = 0b01 -- Independent output mode
//PGxIOCONbits.PENH = 1 -- PWM Generator x controls PWMxH output pin
//PGxIOCONbits.PENL = 1 -- PWM Generator x controls PWMxL output pin
//PGxIOCONbits.OVRENH = 1 -- PWMxH output overridden
//PGxIOCONbits.OVRENL = 0 -- PWMxL output not overridden
//PGxIOCONbits.OVRDAT = 0b00 -- Override data for PWMxH/L (only H uses it) is 0
//PGxIOCONbits.OSYNC = 0b00 -- User output overrides are synchronized to next start of cycle
uint32_t PWM1State[6] = {H_ACTIVE_L_LOW, H_LOW_L_LOW, H_LOW_L_ACTIVE, H_LOW_L_ACTIVE, H_LOW_L_LOW, H_ACTIVE_L_LOW};
uint32_t PWM2State[6] = {H_LOW_L_LOW, H_ACTIVE_L_LOW, H_ACTIVE_L_LOW, H_LOW_L_LOW, H_LOW_L_ACTIVE, H_LOW_L_ACTIVE};
uint32_t PWM3State[6] = {H_LOW_L_ACTIVE, H_LOW_L_ACTIVE, H_LOW_L_LOW, H_ACTIVE_L_LOW, H_ACTIVE_L_LOW, H_LOW_L_LOW};
//Sector 1:
//PWM1H is active, PWM1L is overridden low.
//PWM2H is overridden low, PWM2L is overridden low.
//PWM3H is overridden low, PWM3L is active.
//Sector 2:
//PWM1H is overridden low, PWM1L is overridden low.
//PWM2H is active, PWM2L is overridden low.
//PWM3H is overridden low, PWM3L is active.
//Sector 3:
//PWM1H is overridden low, PWM1L is active.
//PWM2H is active, PWM2L is overridden low.
//PWM3H is overridden low, PWM3L is overridden low.
//Sector 4:
//PWM1H is overridden low, PWM1L is active.
//PWM2H is overridden low, PWM2L is overridden low.
//PWM3H is active, PWM3L is overridden low.
//Sector 5:
//PWM1H is overridden low, PWM1L is overridden low.
//PWM2H is overridden low, PWM2L is active.
//PWM3H is active, PWM3L is overridden low.
//Sector 6:
//PWM1H is active, PWM1L is overridden low.
//PWM2H is overridden low, PWM2L is active.
//PWM3H is overridden low, PWM3L is overridden low.
void PWMInitialization(void)
{
//Set PWM master clock to 400MHz from PLL2 through CLKGEN5
configure_PLL2_Fout_400MHz();
clock_PWM_from_PLL2_Fout();
//Ensure PWM generators are disabled before initializing
PG1CONbits.ON = 0;
PG2CONbits.ON = 0;
PG3CONbits.ON = 0;
//Set PWM Master Period (frequency 100kHz given a 400MHz master clock)
MPER = (4000 << 4); //4000 master clocks; time scale units are 1/16 of a clock
//Set Master Duty Cycle - 25%
MDC = (2000 << 4);
//Set Phase shift - No phase shift
MPHASE = 0;
//Configure PWM Generator 1
PG1CONbits.MDCSEL = 1; //Select MDC as PWM Generator 1's duty cycle register
PG1CONbits.MPERSEL = 1; //Select MPER as PWM Generator 1's period register
PG1CONbits.MPHSEL = 1; //Select MPHASE as PWM Generator 1's phase register
PG1CONbits.MSTEN = 1; //PWM Generator 1 broadcasts software set of UPDREQ control bit and EOC signal to other PWM Generators
PG1CONbits.UPDMOD = 0b000; //PWM buffer update mode is at start of next PWM cycle if UPDREQ = 1
PG1CONbits.TRGMOD = 0b00; //PWM generator 1 operates in single trigger mode
PG1CONbits.SOCS = 0b0000; //Start of cycle is local EOC
PG1CONbits.ON = 0; //PWM Generator 1 is disabled (do not start yet)
PG1CONbits.TRGCNT = 0; //PWM Generator 1 produces 1 PWM cycle when triggered
PG1CONbits.CLKSEL = 0b01; //PWM Generator 1 uses PWM Master Clock, undivided and unscaled
PG1CONbits.MODSEL = 0b000; //PWM Generator 1 operates in Independent Edge PWM mode
PG1IOCONbits.PMOD = 0b01; //PWM Generator 1 Output Mode is Independent Mode
PG1IOCONbits.PENH = 1; //PWM Generator 1 controls the PWM1H output pin
PG1IOCONbits.PENL = 1; //PWM Generator 1 controls the PWM1L output pin
//Override is enabled on PWMxH/L with OVRDAT = 0b00, turning OFF PWM outputs
PG1IOCONbits.OVRENH = 1;
PG1IOCONbits.OVRENL = 1;
PG1IOCONbits.OVRDAT = 0b00;
PG1IOCONbits.OSYNC = 0b0