DSPIC33FJ32MC204-PWM complementary (with dead zone) output program (with source code)

Compilation environment: MPLAB chip: DSPIC33FJ32MC204

#include "p33FJ32MC204.h"
#include "dsp.h"
#include <xc.h>
#include <PPS.H>

/****************Config bit settings* *****************/
// FBS
#pragma config BWRP = WRPROTECT_OFF // Boot Segment Write Protect (Boot Segment may be written)
#pragma config BSS = NO_FLASH // Boot Segment Program Flash Code Protection (No Boot program Flash segment)

// FGS
#pragma config GWRP = OFF // General Code Segment Write Protect (User program memory is not write-protected)
#pragma config GSS = OFF // General Segment Code Protection (User program memory is not code-protected)

// FOSCSEL
#pragma config FNOSC = FRC //Initial oscillator source selection FRC Oscillator Mode (Internal Fast RC (FRC) with divide by N)
#pragma config IESO = ON // Start the device with the internal FRC oscillator source, then automatically switch to the ready user-selected oscillator source Internal External Switch Over Mode (Start-up device with FRC, then automatically switch to user-selected oscillator source when ready)

// FOSC
#pragma config POSCMD = XT //Primary Oscillator Source (Primary Oscillator Disabled)
#pragma config OSCIOFNC = OFF // OSC2 Pin Function (OSC2 pin has clock out function)
#pragma config IOL1WAY = OFF // Peripheral Pin Select Configuration bit allows multiple configuration Peripheral Pin Select Configuration (Allow Only One Re-configuration)
#pragma config FCKSM = CSECME // The clock must be enabled Clock Switching and Monitor (Both Clock Switching and Fail-Safe Clock Monitor are disabled)

//FWDT
#pragma config FWDTEN = OFF // Turn off the watchdog Watchdog Timer Enable (Watchdog timer always enabled)

// FPOR
#pragma config FPWRT = PWR128 // POR Timer Value (128ms)
#pragma config ALTI2C = OFF // Alternate I2C pins (I2C mapped to SDA1/SCL1 pins)
#pragma config LPOL = ON // Motor Control PWM Low Side Polarity bit (PWM module low side output pins have active-high output polarity)
#pragma config HPOL = ON // Motor Control PWM High Side Polarity bit (PWM module high side output pins have active-high output polarity)
#pragma config PWMPIN = ON // Motor Control PWM Module Pin Mode bit (PWM module pins controlled by PORT register at device Reset)

//FICD
#pragma config ICS = PGD3 // Comm Channel Select (Communicate on PGC1/EMUC1 and PGD1/EMUD1)
#pragma config JTAGEN = OFF // JTAG Port Enable (JTAG is Disabled)

void timer2();
void __attribute__((__interrupt__)) _OC1Interrupt( void );
int main(void)
{
        //Perform a clock switch to 40MIPS (80Mhz)
PLLFBD = 38; //M=PLLFBD + 2 = 40
CLKDIVbits.PLLPOST = 0; //N2=2(PLLPOST + 1) = 2
CLKDIVbits.PLLPRE = 0; //N1=PLLPRE + 2 = 2

//unlock OSCCON register
__builtin_write_OSCCONH(0x03);//Switch to the main oscillator mode with PLL After testing, the switch should be successful
__builtin_write_OSCCONL(0x01);//Clock switching is enabled, peripheral pins are unlocked, allowing writing to peripheral pin selection registers, PLL is in an unlocked state, prohibiting the auxiliary oscillator, and requesting to switch to a new oscillator
    //wait for clock to stabilize
while(OSCCONbits. COSC != 0b011);
//wait for PLL to lock
while(OSCCONbits. LOCK != 1) {};
    //clock switch finished

        TRISCbits.TRISC6 = 0;

        //PWM configuration
        //PWM working mode
        P1TCONbits.PTMOD = 0b00;//PWM time base works in free-running mode
        P1TCONbits.PTSIDL = 0; //PWM time base runs in idle mode
        P1TCONbits.PTCKPS = 0b00;//prescaler ratio 1:1
        P1TCONbits.PTOPS = 0b00;//post-divider ratio 1:1
        P1TPER = 3999;//counting period
        //MCPWM module output mode selection
        PWM1CON1bits.PMOD1 = 0;//PWEM pin selection is complementary output mode
        PWM1CON1bits.PMOD2 = 0;
        PWM1CON1bits.PMOD3 = 0;
        PWM1CON1bits.PEN1H = 1; //enable PWMxHy pin for PWM output
        PWM1CON1bits.PEN2H = 1;
        PWM1CON1bits.PEN3H = 1;
        PWM1CON1bits.PEN1L = 1;
        PWM1CON1bits.PEN2L = 1;
        PWM1CON1bits.PEN3L = 1;
        PWM1CON2bits.IUE = 1;//The duty cycle is updated immediately
        // dead zone insertion (complementary PWM output mode only)
        P1DTCON1bits.DTAPS = 0b00;//The prescaler ratio is 1:1
        P1DTCON1bits.DTBPS = 0b00;
        P1DTCON1bits.DTA = 10;
        P1DTCON1bits.DTB = 20;//A dead zone and B dead zone value
        /* Dead Time Unit A selected for PWM active transitions */
        /* Dead Time Unit B selected for PWM inactive transitions */
        P1DTCON2bits.DTS3A = 0; //DTSxA control bits select to insert dead time before high side output is driven active
        P1DTCON2bits.DTS2A = 0;
        P1DTCON2bits.DTS1A = 0;
        P1DTCON2bits.DTS3I = 1; //DTSxI control bit selects dead-time insertion before low-side PWM output is driven active
        P1DTCON2bits.DTS2I = 1;
        P1DTCON2bits.DTS1I = 1;
        //MCPWM module I/O pin control
        P1OVDCONbits.POVD3H = 1;//Pin output is controlled by PWM generator
        P1OVDCONbits.POVD2H = 1;
        P1OVDCONbits.POVD1H = 1;
        P1OVDCONbits.POVD3L = 1;
        P1OVDCONbits.POVD2L = 1;
        P1OVDCONbits.POVD1L = 1;
        //MCPWM module duty cycle initialization
        P1DC1 = 800;
        P1DC2 = 800;
        P1DC3 = 800;
        //Enable PWM pulse generation
        P1TCONbits.PTEN = 1;

        //PWM interrupt
        IFS3bits.PWM1IF = 0;
        IEC3bits.PWM1IE = 1;
        IPC14bits.PWM1IP = 3;


// SRbits.IPL=0b110;//CPU priority is set to 6
// CORCONbits.IPL3=0;//CPU interrupt priority is less than 7
// INTCON1bits.NSTDIS = 0; //0 enables, 1 disables interrupt nesting
// INTCON2bits.ALTIVT = 0; // use standard (default) vector table

        while(1);//Stand still
}

/* PWM1 Interrupt */
void __attribute__((__interrupt__,auto_psv)) _MPWM1Interrupt(void)
{
      PORTCbits.RC6 =! PORTCbits.RC6;
      IFS3bits.PWM1IF = 0;
}

//The set PWM output frequency is 10KHZ, and the frequency measured by the oscilloscope is 10.75KHZ
//Reason: It may be that the PLL_XT frequency selected by the above program is not 80MHZ, it may be more than 79. If you switch to FRC, the effect should be the best, there will be no error

In the results of the oscilloscope, you can see that there are two dead zones, A and B, one is 10 steps long and the other is 20 steps long.

Related formula: