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.