This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320F28335: PWM switching frequency

Part Number: TMS320F28335


Tool/software: Code Composer Studio

I am using TMS320F29335 to run a three-phase inverter. It is working very well at 5 kHz but whenever I increase frequency by using different values as TBPRD I get sinusoidal output instead pulsed inverted output. Is there any other parameter I need to change with TBPRD to change the switching frequency? such as any of these parameters;

int fs=500;          // frequency of the output sinusoidal

InitCpuTimers(); // Start the timer modules
// Configure CPU-Timer 0, 1, and 2 to interrupt every second:
// 150MHz CPU Freq, 1 second Period (in uSeconds
ConfigCpuTimer(&CpuTimer0,150,50); // Configure CPU - Timer0 at 1000 microseconds

  EPwm1Regs.TBPRD = 7500;                         // timer period for 5 KHz, Note: TBPRD = 1/4 ( 150 MHz / 5kHz) = 7,500

Thanks.

  • Hi,

    Abdullah Al Hadi said:
    It is working very well at 5 kHz but whenever I increase frequency by using different values as TBPRD I get sinusoidal output instead pulsed inverted output.


    When you increase the frequency, what is the frequency you are trying to implement?

    Abdullah Al Hadi said:
    Is there any other parameter I need to change with TBPRD to change the switching frequency?

    This should be good enough to change the frequency of the PWM.

    Also, Is your measurement equipment capable of measuring higher frequency signal?

  • Hi Subrahmanya,

    Thank you so much for your response. I am using TBPRD 7500 as 5 kHz, I also applied 7500/4 as 20 kHz and 7500/10 as 50 kHz.

    I used two different oscilloscopes with 100 MHz and 200 MHz bandwidth but both results same.

    If there are no other parameters need to be changed then I assume there may be some circuit problem. I suspect my sensor board. I will investigate it and will return to this thread soon. 

    I am also not very expert in C programing so would you please help me understand what is the meaning of the parameters used in the following line;

    InitCpuTimers(); // Start the timer modules
    // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    // 150MHz CPU Freq, 1 second Period (in uSeconds
    ConfigCpuTimer(&CpuTimer0,150,50); // Configure CPU - Timer0 at 1000 microseconds

    Specially what does the value "50" represent in this line?

    Thanks

  • Hi,
    There parameters indicate as below - 
    150 -> CPU Freq In MHz 
    50 -> Period In USec

  • I checked my sensor board circuit and tested using different connections but the result is the same. Would you please help me understand how this value "50" (the period in Usec) affect the switching signal (if any).

  • Hi,

    ConfigCpuTimer function is for configuring the general purpose timer.
    This has nothing to do with the PWM counter.
    What are you using the CPU timer for? The parameters I mentioned above are applicable for CPU timer.

    Abdullah Al Hadi said:
    Would you please help me understand how this value "50" (the period in Usec) affect the switching signal (if any).

    These should not have an effect on switching of the signal.


  • This is the code I am using. Right now I have 60 Hz reference signal and 5 kHz switching frequency. I want to use around 50 kHz switching frequency. I changed TBPRD accordingly to run my inverter but I don't see the pulsed inverted signal at the output instead only sinusoidal output as if I have a filter but I am not using any filter. 

    //###########################################################################################################################################
    //===========================================================================================================================================
    //
    // Open-loop Control
    //
    //###########################################################################################################################################
    //===========================================================================================================================================

    // Include header files and libraries:
    #include "DSP28x_Project.h" // Header file with basic functions, needed for the micro controller to run
    #include "math.h" // Needed for more advanced mathematical calculations

    //-----------------------------------------------------------------------------------------------------------------------------------
    // Define constants:
    //-----------------------------------------------------------------------------------------------------------------------------------
    #define PI 3.14159265359
    //-----------------------------------------------------------------------------------------------------------------------------------

    //-----------------------------------------------------------------------------------------------------------------------------------
    // Define variables:
    //-----------------------------------------------------------------------------------------------------------------------------------
    double index=0; // index for sine function
    double a=.9; // relative amplitude for the output current waveform (0 to 100%)
    int fs=60; // frequency of the output sinusoidal
    double delta=0.02; // rate in which index will increase
    double sina; // for sinusoidal PWM calculation (Phase A)
    double sinb; // for sinusoidal PWM calculation (Phase B)
    double sinc; // for sinusoidal PWM calculation (Phase C)
    double sind; // for sinusoidal PWM calculation (Phase D)
    //-----------------------------------------------------------------------------------------------------------------------------------


    ///
    //-----------------------------------------------------------------------------------------------------------------------------------
    // Define external function prototypes:
    //-----------------------------------------------------------------------------------------------------------------------------------
    extern void InitSysCtrl(void); // Initialization of the board
    extern void InitPieCtrl(void); // Initialization of interruption
    extern void InitPieVectTable(void); // Initialization of interruption table
    extern void InitCpuTimers(void); // Initialization of CPU timer
    extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float); // Configuration of CPU timer
    //-----------------------------------------------------------------------------------------------------------------------------------

    //-----------------------------------------------------------------------------------------------------------------------------------
    // Prototype statements for functions found within this file:
    //-----------------------------------------------------------------------------------------------------------------------------------

    // Initialization and setup:
    void Gpio_select(void); // Initialization of I/O pins
    void Setup_ePWM1(void); // Function for PWM initialization (phase A)
    void Setup_ePWM2(void); // Function for PWM initialization (phase B)
    void Setup_ePWM3(void); // Function for PWM initialization (phase C)
    void Setup_ePWM4(void); // Function for PWM initialization (phase D)

    //Interruptions:
    interrupt void ePWM1A_compare_isr(void); // Handles PWM interruption
    interrupt void cpu_timer0_isr(void); // Handles time interruption
    //-----------------------------------------------------------------------------------------------------------------------------------


    ////
    //#############################################################################################################################################
    // main code
    //#############################################################################################################################################

    void main(void)
    {
    InitSysCtrl(); // Basic initialization of the chip from DSP2833x_SysCtrl.c

    DINT; // Disable all interrupts

    Gpio_select(); // Set all I/O pins to zero

    // Peripheral initialization process:

    Setup_ePWM1(); // PWM configuration (phase A)
    Setup_ePWM2(); // PWM configuration (phase B)
    Setup_ePWM3(); // PWM configuration (phase C)
    Setup_ePWM4(); // PWM configuration (phase D)

    InitPieCtrl(); // Basic setup of interruption table; from DSP2833x_PieCtrl.c
    InitPieVectTable(); // default ISR's in PIE
    //

    // Assigning the interruption registers with the respective functions:

    EALLOW; // Allow change of interruption register

    PieVectTable.EPWM1_INT = &ePWM1A_compare_isr;
    PieVectTable.TINT0 = &cpu_timer0_isr;

    EDIS; // Disallow change of interruption register

    //

    //Start the peripheral modules:

    InitCpuTimers(); // Start the timer modules
    // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    // 150MHz CPU Freq, 1 second Period (in uSeconds
    ConfigCpuTimer(&CpuTimer0,150,50); // Configure CPU - Timer0 at 1000 microseconds

    // Enable and configure interruptions:

    PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable Timer0 INT in the PIE: Group 1 interrupt register (bit 7)
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // Enable EPWM1A INT in the PIE: Group 3 interrupt (bit 1)

    IER |=5; // enable INT3 for ePWM1 and INT1 for timer

    EINT; // enable interruptions
    ERTM; // enable real time mode

    CpuTimer0Regs.TCR.bit.TSS = 0; // Start timer0
    }
    //##########################################################################################################################################
    // End of main
    //##########################################################################################################################################

    ///
    ///

    //##########################################################################################################################################
    // Declaration of the functions:
    //##########################################################################################################################################

    //-----------------------------------------------------------------------------------------------------------------------------------
    // Initialization of I/O pins
    //-----------------------------------------------------------------------------------------------------------------------------------
    void Gpio_select(void)
    {
    EALLOW;

    GpioCtrlRegs.GPAMUX1.all = 0; // General Purpose I/O: set all pins to zero
    GpioCtrlRegs.GPAMUX2.all = 0; // General Purpose I/O: set all pins to zero

    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // Configure GPIO0 as EPWM1A
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // Configure GPIO1 as EPWM1B
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // Configure GPIO2 as EPWM2A
    GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // Configure GPIO3 as EPWM2B
    GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1; // Configure GPIO4 as EPWM3A
    GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1; // Configure GPIO5 as EPWM3B
    GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 1; // Configure GPIO6 as EPWM4A
    GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 1; // Configure GPIO7 as EPWM4B


    GpioCtrlRegs.GPADIR.all = 0; // Set pin group A for output only
    GpioCtrlRegs.GPBDIR.all = 0; // Set pin group B for output only
    GpioCtrlRegs.GPCDIR.all = 0; // Set pin group C for output only

    EDIS;
    }
    //-----------------------------------------------------------------------------------------------------------------------------------

    //-----------------------------------------------------------------------------------------------------------------------------------
    // Function for PWM configuration (phase A)
    //-----------------------------------------------------------------------------------------------------------------------------------
    void Setup_ePWM1(void)
    {
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // set symmetrical triangular waveform for PWM comparison
    EPwm1Regs.TBPHS.half.TBPHS = 0; // Set PWM phase shift as 0 degree

    EPwm1Regs.TBPRD = 7500; // timer period for 5 KHz, Note: TBPRD = 1/4 ( 150 MHz / 5kHz) = 7,500

    EPwm1Regs.CMPA.half.CMPA = EPwm1Regs.TBPRD / 2; // set duty cycle to 50%, (not used for SPWM)
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // TB_DISABLE assures ePWM1 as Master module
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Synchronize ePWM1 down-stream module

    // The following code segment is required:
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load module on CTR=Zero
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load module on CTR=Zero
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // set pulse high on CMPA up-match
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; // set pulse low on CMPA down-match
    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable dead-time module

    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary, i.e., generating complementary pulse
    EPwm1Regs.DBFED = 5; // Set dead time FED
    EPwm1Regs.DBRED = 7; // Set dead time RED

    EPwm1Regs.ETSEL.all = 0; // disable all ePWM1 interruptions
    EPwm1Regs.ETSEL.bit.INTEN = 1; // interrupt enable for ePWM1
    EPwm1Regs.ETSEL.bit.INTSEL = 5; // interrupt on CMPA down match
    EPwm1Regs.ETPS.bit.INTPRD = 1; // interrupt on first occurrence of that event
    }
    //-----------------------------------------------------------------------------------------------------------------------------------


    //-----------------------------------------------------------------------------------------------------------------------------------
    // Function for PWM configuration (phase B)
    //-----------------------------------------------------------------------------------------------------------------------------------

    void Setup_ePWM2(void)
    {
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // set symmetrical triangular waveform for PWM comparison
    EPwm2Regs.TBPHS.half.TBPHS = 0; // Set PWM phase shift as 0 degree

    EPwm2Regs.TBPRD = 7500; // timer period for 5 KHz, Note: TBPRD = 1/4 ( 150 MHz / 5kHz) = 7,500

    EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPRD / 2; // 50% duty cycle first, not used for SPWM
    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // TB_ENABLE assures ePWM2 as slave module
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Synchronize ePWM2 down-stream module

    // The following code segment is required
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load module on CTR=Zero
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load module on CTR=Zero
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // set pulse high on CMPA up-match
    EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; // set pulse low on CMPA down-match

    EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable dead-time module
    EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary, i.e., generating complementary pulse
    EPwm2Regs.DBFED = 5; // Set dead time FED
    EPwm2Regs.DBRED = 7; // Set dead time RED

    }
    //-----------------------------------------------------------------------------------------------------------------------------------

    //-----------------------------------------------------------------------------------------------------------------------------------
    // Function for PWM configuration (phase C)
    //-----------------------------------------------------------------------------------------------------------------------------------

    void Setup_ePWM3(void)
    {
    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // set symmetrical triangular waveform for PWM comparison
    EPwm3Regs.TBPHS.half.TBPHS = 7500/2; // Set PWM phase shift as 90 degree

    EPwm3Regs.TBPRD = 7500; // timer period for 5 KHz, Note: TBPRD = 1/4 ( 150 MHz / 5kHz) = 7,500

    EPwm3Regs.TBCTL.bit.PHSDIR = TB_DOWN; // Count DOWN on sync (=120 deg)
    EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    //EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through

    EPwm3Regs.CMPA.half.CMPA = EPwm3Regs.TBPRD / 2; // 50% duty cycle first, not used for SPWM
    EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; // TB_ENABLE assures ePWM3 as slave module
    EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Synchronize ePWM3 down-stream module

    // The following code segment is required
    EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load module on CTR=Zero
    EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load module on CTR=Zero
    EPwm3Regs.AQCTLA.bit.CAU = AQ_SET; // set pulse high on CMPA up-match
    EPwm3Regs.AQCTLA.bit.CAD = AQ_CLEAR; // set pulse low on CMPA down-match

    EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable dead-time module
    EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary, i.e., generating complementary pulse
    EPwm3Regs.DBFED = 5; // Set dead time FED
    EPwm3Regs.DBRED = 7; // Set dead time RED

    }

    void Setup_ePWM4(void)
    {
    EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // set symmetrical triangular waveform for PWM comparison
    EPwm4Regs.TBPHS.half.TBPHS = 7500/2; // Set PWM phase shift as 90 degree

    EPwm4Regs.TBPRD = 7500; // timer period for 5 KHz, Note: TBPRD = 1/4 ( 150 MHz / 5kHz) = 7,500

    EPwm4Regs.TBCTL.bit.PHSDIR = TB_DOWN; // Count DOWN on sync (=120 deg)
    EPwm4Regs.TBCTL.bit.PRDLD = TB_SHADOW;

    EPwm4Regs.CMPA.half.CMPA = EPwm4Regs.TBPRD / 2; // 50% duty cycle first, not used for SPWM
    EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE; // TB_ENABLE assures ePWM4 as slave module
    EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Synchronize ePWM4 down-stream module

    // The following code segment is required
    EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load module on CTR=Zero
    EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load module on CTR=Zero
    EPwm4Regs.AQCTLA.bit.CAU = AQ_SET; // set pulse high on CMPA up-match
    EPwm4Regs.AQCTLA.bit.CAD = AQ_CLEAR; // set pulse low on CMPA down-match

    EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Enable dead-time module
    EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary, i.e., generating complementary pulse
    EPwm4Regs.DBFED = 5; // Set dead time FED
    EPwm4Regs.DBRED = 7; // Set dead time RED

    }

    //-----------------------------------------------------------------------------------------------------------------------------------


    //-----------------------------------------------------------------------------------------------------------------------------------
    // Calculates next PWM pulse widths, based on the value calculated on "cpu_timer0_isr":
    //-----------------------------------------------------------------------------------------------------------------------------------
    interrupt void ePWM1A_compare_isr(void)
    // ISR runs every (1/fpwm) seconds (PWM-frequency = 5 KHz)
    {
    // The following sequence calculates the value for the next pulse width:
    EPwm1Regs.CMPA.half.CMPA = EPwm1Regs.TBPRD - (int)(((a*sina+0.9999)/2)*EPwm1Regs.TBPRD);
    EPwm2Regs.CMPA.half.CMPA = EPwm2Regs.TBPRD - (int)(((a*sinb+0.9999)/2)*EPwm2Regs.TBPRD);
    EPwm3Regs.CMPA.half.CMPA = EPwm3Regs.TBPRD - (int)(((a*sinc+0.9999)/2)*EPwm3Regs.TBPRD);
    EPwm4Regs.CMPA.half.CMPA = EPwm4Regs.TBPRD - (int)(((a*sind+0.9999)/2)*EPwm4Regs.TBPRD);
    // EPwm4Regs.CMPA.half.CMPA = EPwm4Regs.TBPRD - (int)((a*(sind+0.9999)/2)*EPwm4Regs.TBPRD);
    //
    //

    EPwm1Regs.ETCLR.bit.INT = 1; // Clear ePWM1 Interrupt flag

    // Acknowledge this interrupt to receive more interrupts from group 3:
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

    }
    //-----------------------------------------------------------------------------------------------------------------------------------

    //-----------------------------------------------------------------------------------------------------------------------------------
    // Performs calculations for control at each 1000 microseconds :
    //-----------------------------------------------------------------------------------------------------------------------------------
    interrupt void cpu_timer0_isr(void)
    {
    CpuTimer0.InterruptCount++; // Increase timer0 counter
    double angle;


    angle=2*PI* 0.00005*fs*CpuTimer0.InterruptCount; // Calculates the argument for the sine function

    // Calculation of the next pulse widths for ePWM:
    sina=(sin(fmod(angle,2*PI)));
    sinb=(-1)*sina;
    // sinb=(sin(fmod(angle+2*PI/3,2*PI))); // Note the phase shift between the phases
    // sinc=(sin(fmod(angle+4*PI/3,2*PI)));
    sinc=sina;
    sind=(-1)*sinc;
    //


    // Acknowledge this interrupt to receive more interrupts from group 1:
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }
    //-----------------------------------------------------------------------------------------------------------------------------------


    //#############################################################################################################################################
    // End of function declaration
    //#############################################################################################################################################


    //.............................................................................................................................................
    //
    // Meaning of the CMPA register and up-down mode operation:
    //
    // /\ /\ /\ /\ /\
    // / \ / \ / \ / \ / \ /
    // -------+----+------+----+------+----+------+----+------+----+------+----------CMPA
    // / \ / \ / \ / \ / \ /
    // / \ / \ / \ / \ / \ /
    // / \/ \/ \/ \/ \/
    // |-------------|
    // TBPRD
    //................................................................................................................................................

  • Hi,

    As I mentioned earlier, the PWM outputs generated by the MCU are digital outputs.
    I would suggest to check your measurement circuitry,
    Is your measurement equipment capable of measuring higher frequency signal?
    Have you enabled some option to filter or averaging in the scope used for measurement?
    Simply changing the period value doesn't make the output sinusoidal. You'll have to check above.

  • This thread will be closing soon due to a lack of replies. Please respond here or start a new thread if you have another issue.

    Regards,
    Cody