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.

pwm phase shift



Hello, 

I was wondering how I could have three PWM signals from three different GPIOs produce a PWM signal which is phase sifted by a certain degree. 

How would I go about this approach ?

Thanks. 

  • Hi Rajan,

    This is very well explained in ePWM user guide. I can see the tags mentioning F28335 as your device.

    Go through the user guide for ePWM peripheral that can be found here:

    Codes and waveforms are shared too.

    Regards,
    Gautam

  • Hi Rajan,

    Which device are you using? You can generate multiple PWMs from different PWM instances on different GPIOs.
    You can maintain phase shift across multiple PWMs - refer to PWM synchronization scheme.

    -Bharathi.
  • Hello Guatam,

    I did have a look at this document but I am unclear on how to have a PWM signal to be exactly 120 degree phase shift from one another.

    Currently I am able to visually look on the scope and see that there is about a 120 degree phase shift but I want it to be exactly 120 degrees. I am using the following code :

    void InitEPwm1Example()
    {
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    EPwm1Regs.TBPRD = PRD1; // Set timer period
    EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
    EPwm1Regs.TBCTR = 0x0000; // Clear counter

    // Setup TBCLK
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4; // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV2;
    //EPwm1Regs.TBCTL.bit.PRDLD = TB_ENABLE;

    // Setup compare
    EPwm1Regs.CMPA.half.CMPA = PRD1/2;

    // Set actions
    //EPwm1Regs.AQCTLA.bit.PRD = AQ_TOGGLE;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;
    }

    void InitEPwm2Example()
    {
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    EPwm2Regs.TBPRD = PRD2; // Set timer period
    EPwm2Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
    EPwm2Regs.TBCTR = 0xa600; // Clear counter

    // Setup TBCLK
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Disable phase loading
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4; // Clock ratio to SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV2;
    //EPwm2Regs.TBCTL.bit.SYNCOSEL = 1;
    EPwm2Regs.TBCTL.bit.PHSDIR = 1;
    //EPwm1Regs.TBCTL.bit.PRDLD = TB_ENABLE;

    // Setup compare
    EPwm2Regs.CMPA.half.CMPA = PRD2/2;

    // Set actions
    //EPwm1Regs.AQCTLA.bit.PRD = AQ_TOGGLE;
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
    EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;
    }

    I am unsure of what the formula is , I read on some threads that the formula is Counts/Period * 360 = TheDegreeYouWant. Please let me know where I am going wrong in the code section.

    Thank you,

    Rajan Joshi
  • Rajan, the issue you're facing is because you're using TBCTR for enabling the shift and the clocks for ePWMs are not in-sync. As I can see above TMCLKSYNC are individually configured. Try this change first:

      EALLOW;  
           SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;      // DISABLE TBCLK TILL EPWM CONFIGURATION 
      EDIS; 
    
    
    //ALL PWM CONFIGURATIONS
    
    
    //AND FINALLY:
    
    EALLOW;
             SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;      // ENABLE TBCLK TILL EPWM CONFIGURATION 
    EDIS;

    You've done 2 times for both ePWM configuration. If this doesn't work try configuring TBPHS register instead of TBCTR.

    Regards,

    Gautam

  • Gutam, thank you for the quick response. The clock sync did help in changing phase of the PWM.

    I was wondering if I could be specific about how much the offset would be ? Since i am using a driver to power a three phase motor, I need the waves to be 120 degrees out of phase, is it possible to do this?

    Are there any examples that I could look at that could help me?

    Thanks !

    Rajan Joshi
  • Rajan Joshi said:

    I was wondering if I could be specific about how much the offset would be ? Since i am using a driver to power a three phase motor, I need the waves to be 120 degrees out of phase, is it possible to do this?

    Can you be clearer about the offset you're talking about? Are you still observing any offset during the phase shift?


    Regards,

    Gautam

  • Currently I have three PWM signals. I would like to have a phase shift of 120 degrees for each of the signals. So, first one starts at 0 degrees second one at 120 degrees phase shift from the first one and the last one at a 240 degree phase shift from the first one.

    I now disable the sync when I call the config of the PWM functions as such:

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    InitEPwm1Example();
    InitEPwm2Example();
    InitEPwm3Example();

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

    Where,
    void InitEPwm1Example()
    {


    EPwm1Regs.TBPRD = PRD1; // Set timer period
    EPwm1Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
    EPwm1Regs.TBCTR = 0x0000; // Clear counter

    // Setup TBCLK
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 7; // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = 4;
    //EPwm1Regs.TBCTL.bit.PRDLD = TB_ENABLE;

    // Setup compare
    EPwm1Regs.CMPA.half.CMPA = PRD1/2;

    // Set actions
    //EPwm1Regs.AQCTLA.bit.PRD = AQ_TOGGLE;
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;

    }
    void InitEPwm2Example()
    {


    EPwm2Regs.TBPRD = PRD2; // Set timer period
    EPwm2Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
    EPwm2Regs.TBCTR = 0x8000;

    // Setup TBCLK
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up
    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Disable phase loading
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 7; // Clock ratio to SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV = 4;
    //EPwm2Regs.TBCTL.bit.SYNCOSEL = 1;
    EPwm2Regs.TBCTL.bit.PHSDIR = 1;
    //EPwm1Regs.TBCTL.bit.PRDLD = TB_ENABLE;

    // Setup compare
    EPwm2Regs.CMPA.half.CMPA = PRD2/2;

    // Set actions
    //EPwm1Regs.AQCTLA.bit.PRD = AQ_TOGGLE;
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM1A on Zero
    EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;

    }

    The phase are being adjusted by TBCTR, so when I vary that number the signal will be manipulated. However, I am not sure how exactly this varies the signal. So, what I am trying to ask is that is there a way of being specific for the phase shift of the second signal compared to the first by 120 degrees instead of trial and error with different TBCTR values?

    Thank you,

    Rajan Joshi
  • Hey Gautam, 

    I was able to go through the pdf of PWM and able to find the phase shift. 

    It is located on page 86 of the manual ! 

    Thank you for the help !

    Rajan Joshi

  • Great! Yeah.. all the PWM configurations are very well given in the userguide and that's what I pointed out in my first post:
    e2e.ti.com/.../1830650

    Goodluck & Regards,
    Gautam