17.5.1.2 Six-Step Commutation – PWM Scheme 2

In this PWM scheme, three switches are used to control the two active phases. In a given sector, one active phase is driven with a complementary PWM waveform and the other active phase has only its low side driven low at 100% duty cycle, as shown in Figure 17-41. Like Scheme 1, overrides are used to control the outputs in each sector.

Figure 17-41. Six-Step PWM Scheme 2 Waveform

In this scheme, Complementary Output mode is used and overridden as needed in each sector. The same three-phase host/client synchronization technique is used as in Scheme 1.

Configuration Summary:

  • Independent Edge PWM mode
  • Complementary Output mode
  • Master Period and Duty Cycle Used
  • Override State is Dependent on Sector State
  • Dead time is applied to the Complementary PWM Signal

Six-Step PWM Scheme 2 Code

#include<stdint.h>
//For delay function
#define FCY 8000000                 //CPU frequency in Hz
#include "libpic30.h"


void PWMInitialization(void);

#define H_ACTIVE_L_ACTIVE  0x000C0000
   //PGxIOCONbits.PMOD = 0b00 -- Complementary output mode
   //PGxIOCONbits.PENH = 1 -- PWM generator x controls PWMxH pin
   //PGxIOCONbits.PENL = 1 -- PWM generator x controls PWMxL pin
   //PGxIOCONbits.OVRENH = 0 -- Override not enabled on PWMxH pin
   //PGxIOCONbits.OVRENL = 0 -- Override not enabled on PWMxL pin
#define H_LOW_L_HIGH         0x000C3400
   //PGxIOCONbits.PMOD = 0b00 -- Complementary output mode
   //PGxIOCONbits.PENH = 1 -- PWM generator x controls PWMxH pin
   //PGxIOCONbits.PENL = 1 -- PWM generator x controls PWMxL pin
   //PGxIOCONbits.OVRENH = 1 -- Override enabled on PWMxH pin
   //PGxIOCONbits.OVRENL = 1 -- Override enabled on PWMxL pin
   //PGxIOCONbits.OVRDAT = 0b01 -- PWMxH pin overridden high, PWMxL pin overridden low
#define H_LOW_L_LOW             0x000C3000
   //PGxIOCONbits.PMOD = 0b00 -- Complementary output mode
   //PGxIOCONbits.PENH = 1 -- PWM generator x controls PWMxH pin
   //PGxIOCONbits.PENL = 1 -- PWM generator x controls PWMxL pin
   //PGxIOCONbits.OVRENH = 1 -- Override enabled on PWMxH pin
   //PGxIOCONbits.OVRENL = 1 -- Override enabled on PWMxL pin
   //PGxIOCONbits.OVRDAT = 0b00 -- PWMxH pin overridden low, PWMxL pin overridden low

uint16_t state = 0;

uint32_t PWM1State[6] = {H_ACTIVE_L_ACTIVE, H_LOW_L_LOW, H_LOW_L_HIGH, H_LOW_L_HIGH, H_LOW_L_LOW, H_ACTIVE_L_ACTIVE};
uint32_t PWM2State[6] = {H_LOW_L_LOW, H_ACTIVE_L_ACTIVE, H_ACTIVE_L_ACTIVE, H_LOW_L_LOW, H_LOW_L_HIGH, H_LOW_L_HIGH};
uint32_t PWM3State[6] = {H_LOW_L_HIGH, H_LOW_L_HIGH, H_LOW_L_LOW, H_ACTIVE_L_ACTIVE, H_ACTIVE_L_ACTIVE, H_LOW_L_LOW};

//Sector 1:
//PWM1 has complementary outputs, both controlled by the PWM generator.
//PWM2 has both outputs overridden to low.
//PWM3 has High output overridden to low, Low output overridden to high.
//Sector 2:
//PWM1 has both outputs overridden to low.
//PWM2 has complementary outputs, both controlled by the PWM generator.
//PWM3 has High output overridden to low, Low output overridden to high.
//Sector 3:
//PWM1 has High output overridden to low, Low output overridden to high.
//PWM2 has complementary outputs, both controlled by the PWM generator.
//PWM3 has both outputs overridden to low.
//Sector 4:
//PWM1 has High output overridden to low, Low output overridden to high.
//PWM2 has both outputs overridden to low.
//PWM3 has complementary outputs, both controlled by the PWM generator.
//Sector 5: 
//PWM1 has both outputs overridden to low.
//PWM2 has High output overridden to low, Low output overridden to high.
//PWM2 has complementary outputs, both controlled by the PWM generator.
//Sector 6:
//PWM1 has complementary outputs, both controlled by the PWM generator.
//PWM2 has High output overridden to low, Low output overridden to high.
//PWM3 has both outputs overridden to low.


void Delay() {
    __delay_us(50); //Delay 5 PWM cycles
}

int main()
{
    
    
   //Initialize PWM module
    PWMInitialization();

    while(1)
    {
        for(state = 0; state < 6; state++)
        {
            //Delay is used to simulate BLDC commutation.
            //In practical application, commutation state transition will be based on feedback from Motor.
            Delay();
            
            PG1IOCON = PWM1State[state];
            PG2IOCON = PWM2State[state];
            PG3IOCON = PWM3State[state];
        }
    }
}
void PWMInitialization(void)
{
    //Ensure PWM Generators 1-3 are disabled before configuring
    PG1CONbits.ON = 0;
    PG2CONbits.ON = 0;
    PG3CONbits.ON = 0;
    
    //Set PWM master clock to 400MHz from PLL2 through CLKGEN5
    configure_PLL2_Fout_400MHz();
    clock_PWM_from_PLL2_Fout();
    
    //Set PWM Period -- 100kHz given a 400MHz PWM master clock
    MPERbits.MPER = (4000 << 4); //Time base units are 1/16 of a PWM clock
    //Set Duty Cycle-- 25%
    MDCbits.MDC = (2000 << 4);
    //Set Phase shift - No phase shift
    MPHASEbits.MPHASE = 0;
    
    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
    
    //PWM Generator broadcasts software set of UPDREQ control bit and EOC signal to other PWM Generators
    PG1CONbits.MSTEN = 1; 

    PG1CONbits.UPDMOD = 0b000;    //PWM Buffer Update Mode is at start of next PWM cycle if UPDREQ = 1
    PG1CONbits.TRGMOD = 0b00;     //PWM generator operates in Single Trigger Mode
    PG1CONbits.SOCS = 0b0000;     //Start of Cycle is local EOC 
    
    
    PG1CONbits.CLKSEL = 0b01;     //PWM Generator uses PWM Master Clock, undivided and unscaled
    PG1CONbits.MODSEL = 0b000;    //PWM Generator operates in Independent Edge PWM mode
    
    
    PG1IOCONbits.PMOD = 0b00;    //PWM Generator 1 Output Mode is Complementary Mode
    PG1IOCONbits.PENH = 1;       //PWM Generator 1 controls the PWM1H output