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: How to generate 3-phase shifted PWM signals with variable frequency using TMS320F28335 DSP?

Part Number: TMS320F28335

Tool/software: Code Composer Studio

Hello,

I would like to generate 3-phase shifted PWM signals using TMS320F28335 DSP. But I want to vary the PWM signal frequency from 20 kHz to 24 kHz periodically with a step change of 1 kHz and the duty ratio will be constant. So, the frequency of the PWM1 is supposed to vary from 20 kHz to 24 kHz and the other two PWM signals, PWM2 and PWM3, will follow the PWM1 with a phase of 120 degree. As a first approach, I am trying to vary the frequency of PWM1 where I am comparing the TBCTR value with the TBPRD to update the TBPRD and CMPA values. To avoid delay because of calculation, I have stored the required TBPRD values in an array. But the PWM1 is not working as I expect it to be. 

Could anyone please give me suggestions to solve this problem?

Mohammad Arifur Rahman

  • Start from this example:

    http://dev.ti.com/tirex/explore/node?node=ANQtAx1d.2Tq4rBvalR55g__gYkahfz__LATEST

    You will need to update,

    TBPRD,

    CMPA,CMPB,

    TBPHS (only slave PWMs)

  • Mohammad,

    You should be able to update the TBPRD registers. Please note that you may experience some jitter between the 3 phase shifted PWMs due to the frequency shifting you are implementing. This will only occur when you update one or two PWM's TBPRD value, but not the others inside of a PWM period.

    I would also recommend that you look into using the shadow loading feature. You may not need it if you define a safe window in which to update the TBPRD value, but it may still be a helpful feature for you.

    Updating TBPRD should be pretty simple, you just write to the register. If you are not seeing the value change I would assume you have some sort of issue in your code that you need to debug. Try using the memory browser to read the values. Single stepping can help you rule out other pieces of code that may be stepping on the value that you just wrote. And finally writing to a RAM location may be a good idea to test your function.

    Regards,
    Cody 

  • Cody,

    Thank you for your suggestion. I am using the shadow mode right now. I am also using an interrupt to update the the TBPRD and CMPA values while the interrupt is coming after every 1uS. I have attached the code below. Is comparing the TBCRT value with CMPA the right way for updating the TBPRD and CMPA values?

    PWM initilization :


    void Setup_ePWM(void)
    {
    ////////////////////////////////////////////
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 3;
    EPwm1Regs.TBCTL.bit.CTRMODE = 0;


    EPwm1Regs.TBPRD = freq[0];
    EPwm1Regs.CMPA.half.CMPA = duration[0];

    EPwm1Regs.AQCTLA.bit.ZRO=2;
    EPwm1Regs.AQCTLA.bit.CAU=1;

    EPwm1Regs.CMPCTL.bit.LOADAMODE=0;
    EPwm1Regs.CMPCTL.bit.SHDWAMODE=0;

    }

    Updating TBPRD and CMPA inside ISR:

    interrupt void cpu_timer0_isr(void){
    if (pwm1count==16){
    pwm1count=0;
    }
    if (EPwm1Regs.TBCTR==EPwm1Regs.CMPA.half.CMPA){
    EPwm1Regs.TBPRD = freq[pwm1count];
    EPwm1Regs.CMPA.half.CMPA = duration[pwm1count];
    pwm1count++;
    }

    PieCtrlRegs.PIEACK.all = 1;
    }

  • Mohammad,

    have you verified that the code in that if statement ever gets executed? The odds of TBCTR being exactly equal to CMPA at the instance that the "if statement" is evaluated is very low. I suspect you will rarely if ever see this code run.

    Just set the TBPRD value and CMPA values. If you would like to define a save window to update the values then use a range of values rather than an exact match.

    Regards,
    Cody 

  • Hi Cody,

    I got better results using a range for updating the TBPRD values. I have implemented it for 3-phase shifted PWMs.

    Time period updating code:

    if (EPwm1Regs.TBCTR>=600 && EPwm1Regs.TBCTR<=618){
    EPwm1Regs.TBPRD = freq[pwm1count];
    EPwm1Regs.CMPA.half.CMPA = duration[pwm1count];

    EPwm2Regs.TBPHS.half.TBPHS = phase[pwm1count];
    EPwm2Regs.TBPRD = freq[pwm1count];
    EPwm2Regs.CMPA.half.CMPA = duration[pwm1count];

    EPwm3Regs.TBPHS.half.TBPHS = phase3[pwm1count];
    EPwm3Regs.TBPRD = freq[pwm1count];
    EPwm3Regs.CMPA.half.CMPA = duration[pwm1count];

    }

    Now the PWMs look as below:

    Thank you very much for your help. 

    Mohammad Arifur Rahman