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.

Figure 17-40. Six-Step PWM Scheme 1 Waveform

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