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.

TMS320F28027F: Unwanted Frequency variation when using HRPWM

Part Number: TMS320F28027F
Other Parts Discussed in Thread: C2000WARE

Hi Team,

I am using HRPWM Module for high-resolution period control. After the initialization, When I hard code the resisters for a fixed frequency and dutycycle, I notice that the frequency is not constant on the oscilloscope.

For example, I fix the values of the registers for 187 kHz. I notice that the frequency on the oscilloscope varies by 200 Hz (between 187.0 kHz to 187.2 kHz). This variation further increases at higher frequencies, for 375 kHz it is around 400 Hz.

Here is the initialization of EPWM and HRPWM Module:

uint16_t Time_counter=30000;
uint16_t frequency_ref_KHz=125; // Initializing PWM frequency

void InitEPwm1Example()
{
    EALLOW;

    TBPRD_Counter=Time_counter/frequency_ref_KHz; // Calculation
    EPwm1Regs.TBPRD = TBPRD_Counter;                 // Set timer period
    EPwm1Regs.TBPRDHR =0x0000;
    EPwm1Regs.TBPHS.half.TBPHS = 0x0000;            //  Used for Sync. of multiple PWM channels, we are using only one channel (2 output) , It os already disabled below
    EPwm1Regs.TBCTR = 0x0000;                       // Clear counter
    EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;             // set Shadow load so that TBPRD is safe this way

    // Setup TBCLK
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count updown
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Disable  loading // To enable
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;          // Slow so we can observe on the scope
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;// Recommended for High Resolution : zero or Comp B

    /*
     The PWM Uses EPWM1A to create EPWM1B signal (It does not use EPWM1B)
     Refer to fig. 3.29
     The PWM is initialised to active high. The Deadband full enable allows Dead band on both rising edges
     */
    // Load registers every ZERO
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // This allows shadowing of Duty cycle compare registers
    //EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // This allows shadowing of Duty cycle compare registers
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // The data will be transferred when counter is zero
    //EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // The data will be transferred when counter is zero

    // Setup compare
    EPwm1Regs.CMPA.half.CMPA = TBPRD_Counter>>1;      // Duty cycle initialized to 50%
    EPwm1Regs.CMPA.half.CMPAHR = 0x00;       // initialize HRPWM extension for duty cycle 1<<8

    // Set actions
    //Channel B
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;         // When Duty counter reaches the set value while incrementing : The PWM goes high
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;  // When Duty counter reaches the set value while decrementing : The PWM goes low

    // Active high complementary PWMs - Setup the band
    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // Fig:3.29 | S1 and S0 are 1 and 1 | Both of them come from delay ckt
    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;  // Fig:3.29 | It creates EPWM1B by inverting  and delaying EPWM1B
    EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;  // Fig:3.29 | It uses only EPWM1A as an input
    EPwm1Regs.DBRED = EPWM1_MAX_DB; // This initializes dead band for rising edge
    EPwm1Regs.DBFED = EPWM1_MAX_DB; // This initializes dead band for falling edge

    // Interrupt where we will change the deadband
    EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;       // The interrupt ISR happens after counter reaches 0 after decrementing
    EPwm1Regs.ETSEL.bit.INTEN = 0;                  // Enable INT
    EPwm1Regs.ETPS.bit.INTPRD = ET_DISABLE;             // Generate INT on 3rd event ET_DISABLE

    // Settings for Enabling/Disabling PWM
    //EPwm1Regs.TZCLR.all = 0; // No Effect
    EPwm1Regs.TZCLR.bit.OST = 1; // Clears previous trip
    EPwm1Regs.TZSEL.bit.OSHT1 = 1;  // Initialize TZ1 for one-shot trip
    EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
    EPwm1Regs.TZEINT.bit.OST = 1; // allowing interrupt
    //EPwm1Regs.TZFRC.bit.OST= 1; // Disabling PWM, reset counter (TBCTR)  before allowing


    //HR Initialisation
    EPwm1Regs.HRCNFG.all = 0x0;
    EPwm1Regs.HRCNFG.bit.EDGMODE = HR_BEP;          // MEP control on both edges
    EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP;          // CMPAHR and TBPRDHR HR control
    EPwm1Regs.HRCNFG.bit.HRLOAD  = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD
    EPwm1Regs.HRCNFG.bit.AUTOCONV = 1;  // Enable autoconversion for HR period then calculation for TBPRDHR using MEP steps is not needed

    EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 1;  // Enable TBPHSHR sync (required for up-down count HR control even if phase control is not used)
    EPwm1Regs.HRPCTL.bit.HRPE = 1;    // Turn on high-resolution period or duty control.

    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;  // Synchronizes TBCLK with the EPWM
    EPwm1Regs.TBCTL.bit.SWFSYNC = 1;      // This generates one time synchronization signal for EPWM

    EDIS;
}

After this, I fix the values of registers.

 

         EPwm1Regs.TBPRD =160;
         EPwm1Regs.CMPA.half.CMPA = 80 ;

         EPwm1Regs.TBPRDHR = 100<<8;
         EPwm1Regs.CMPA.half.CMPAHR = 50<<8;

When I look at the values of the registers in the debug mode ;

I can verify that they are constant (TBPRD, TBPRDHR, and CMPA).

I noticed that during the operation, MEP_ScaleFactor is varying between 115-116. I do not think this should cause this large error.

This unwanted variation in frequency negates the advantage of using the HRPWM module.

I want to know (1) why it happens? (2) how to remove this unwanted variation in frequency.

  • A small correction:

    For the debug mode screenshot provided above: I had initialized the EPWM registers with the following value 

    I can verify that they are constant (TBPRD, TBPRDHR, and CMPA).

      EPwm1Regs.TBPRD =80;
      EPwm1Regs.CMPA.half.CMPA = 40 ;
    
      EPwm1Regs.TBPRDHR = 100<<8;
      EPwm1Regs.CMPA.half.CMPAHR = 50<<8;

  • Are you using the SFO? If not please implement and let me know the results.

    Regards,
    Cody 

  • Hi Cody,

    I am using SFO as per the description mentioned in Technical Reference Manual (TMS320F2802x,TMS320F2802xx Piccolo).

    I can observe that 'MEP_ScaleFactor' and 'HRMSTEP' are updated.

      for(;;)
       {
           int status;
           status = SFO_INCOMPLETE;
           while (status==SFO_INCOMPLETE) {
           status = SFO();
           }
           if(status!=SFO_ERROR) { // IF SFO() is complete with no errors
           EALLOW;
           EPwm1Regs.HRMSTEP=MEP_ScaleFactor;
           EDIS;
           }
       }

    I observed that:

    • when the HRPWM registers are initialized with a non-zero constant value then the variation in frequency is close to 120 Hz at 75 kHz PWM.

    EPwm1Regs.TBPRD =400; //75 kHz
    EPwm1Regs.CMPA.half.CMPA = 200 ;
    
    EPwm1Regs.TBPRDHR = 100<<8;
    EPwm1Regs.CMPA.half.CMPAHR = 50<<8;

    • when the HRPWM registers are initialized with a zero constant value then the variation in frequency is close to 10 Hz at 75 kHz PWM.

                 EPwm1Regs.TBPRD =400;
                 EPwm1Regs.CMPA.half.CMPA = 200 ;
    
                 EPwm1Regs.TBPRDHR = 0;
                 EPwm1Regs.CMPA.half.CMPAHR = 0;

    • when the HRPWM functionality is turned off, the variation in frequency is close to 10 Hz at 75 kHz PWM

    In the initialization

    EPwm1Regs.HRPCTL.bit.HRPE = 0;    // Turn off high-resolution period or duty control.

                 EPwm1Regs.TBPRD =400;
                 EPwm1Regs.CMPA.half.CMPA = 200 ;
    
                 EPwm1Regs.TBPRDHR = 0;
                 EPwm1Regs.CMPA.half.CMPAHR = 0;

  • I don't believe you should have so much jitter. And writing a 0 into the HR registers mostly disables the HR enhancements, so the fact that this go down to 10Hz indicates the rest of the jitter is probably coming from the HR PWM.

    Are you running the SFO periodically? How many nS is this jitter?

    Can you run the follow example and see if you still see the same variation? "C:\ti\c2000\C2000Ware_3_04_00_00\device_support\f2802x\examples\structs\hrpwm_prdupdown_sfo_v6" 


    Regards,
    Cody 

  • Hi Cody,

    1. Yes, I am running SFO periodically under main() as shown in 'hrpwm_prdupdown_sfo_v6'

    2. The jitter is close to 18 nS

    3. I ran the example and I didn't notice jitter (2-3 nS instead of 18 nS)

    It turns out that this specific micro-controller (custom mount on a PCB) is the isssue. The code (example as well as my own code) works perfectly with Launchpad or with another micro-controllers (custom mount on 3 other PCB) with the same part number.

    Do you know what could cause this behavior? The micro-controller is performing all other tasks (Interrupts, PWM, ADC conversions) correctly.