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.
Dear team:
I used HRPWM1and HRPWM2to do synchronous frequency conversion experiments, The cycle, CMPA and CMPB of HRPWM2 follow HRPWM1.
1, When EPwm1Regs.CMPA.bit.CMPAHR is a fixed value, the frequency conversion is normal.
When EPwm1Regs.CMPA.bit.CMPAHR changes with frequency, the first cycle of frequency conversion will be abnormal, and the second cycle will be normal.
Configuration is below:
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; EALLOW; EPwm2Regs.EPWMXLINK.bit.TBPRDLINK = 0; EPwm2Regs.EPWMXLINK.bit.CMPALINK = 0; EPwm2Regs.EPWMXLINK.bit.CMPBLINK = 0; //EPwm2Regs.GLDCTL.bit.GLDPRD=2; EPwm2Regs.GLDCTL.bit.OSHTMODE =1; EPwm2Regs.GLDCTL.bit.GLDMODE = 0;//0010: Load on either Counter = 0, or Counter = Period EPwm2Regs.GLDCTL.bit.GLD = 1; EPwm2Regs.GLDCFG.all =0x001F; EPwm2Regs.EPWMXLINK.bit.GLDCTL2LINK = 0;//0000: ePWM1 EPwm2Regs.GLDCTL2.bit.OSHTLD =1; EDIS; EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; EALLOW; SyncSocRegs.SYNCSELECT.bit.EPWM4SYNCIN = 0; EDIS; EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
2, The following configuration will result in normal frequency conversion, but out of synchronization with phase difference:
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; EALLOW; SyncSocRegs.SYNCSELECT.bit.EPWM4SYNCIN = 0; EDIS; EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
PWM mode: up-down
Best regards
yellow:HRPWM1
pink:HRPWM2
I am sorry,The above description is not correct。 EPwm1Regs.CMPA.bit.CMPAHR is always a fixed value.
1、 When EPwm1Regs.TBPRDHR is a fixed value, the frequency conversion is normal.
2、When EPwm1Regs.TBPRDHR changes with frequency( from 120k to 310k or from 310k to 120k), the first cycle of frequency conversion will be abnormal, and the second cycle will be normal.
a、The cycle, CMPA and CMPB of HRPWM2 follow HRPWM1 as follow
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EALLOW;
EPwm2Regs.EPWMXLINK.bit.TBPRDLINK = 0;
EPwm2Regs.EPWMXLINK.bit.CMPALINK = 0;
EPwm2Regs.EPWMXLINK.bit.CMPBLINK = 0;
//EPwm2Regs.GLDCTL.bit.GLDPRD=2;
EPwm2Regs.GLDCTL.bit.OSHTMODE =1;
EPwm2Regs.GLDCTL.bit.GLDMODE = 0;//0010: Load on either Counter = 0, or Counter = Period
EPwm2Regs.GLDCTL.bit.GLD = 1;
EPwm2Regs.GLDCFG.all =0x001F;
EPwm2Regs.EPWMXLINK.bit.GLDCTL2LINK = 0;//0000: ePWM1
EPwm2Regs.GLDCTL2.bit.OSHTLD =1;
EDIS;
b、The hrpwm1 register is updated as follows
LLCDuty_HR = (Uint16) ((0.4)*65536);
fLLCPrd = 50000/fLLCFreq + 0.5f;
LLCPrd = (Uint16)(fLLCPrd);
LLCPrd_HR = (Uint16)((fLLCPrd-LLCPrd)*65536);
EPwm1Regs.TBPRD = LLCPrd;
EPwm1Regs.TBPRDHR =LLCPrd_HR;
EPwm1Regs.CMPA.bit.CMPA = LLCPrd/2-LLCDuty;
EPwm1Regs.CMPA.bit.CMPAHR =65536-LLCDuty_HR ;
EPwm1Regs.CMPB.bit.CMPB = LLCPrd/2+LLCDuty;
EPwm1Regs.CMPB.bit.CMPBHR = LLCDuty_HR ;
c、When the TBCTR is greater than 0, Configure EPwm1Regs.GLDCTL2.bit.OSHTLD = 1 so that PWM1 and PMW2 update when TBCTR equals 0 in the next cycle
EPwm1Regs.GLDCTL2.bit.OSHTLD =1;
PWM configuration is as follows
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
SyncSocRegs.SYNCSELECT.bit.SYNCOUT = 0;
EDIS;
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.TBCTL2.bit.PRDLDSYNC = 0;
EPwm1Regs.TBCTR = 0;
EPwm1Regs.TBPHS.bit.TBPHS = 0;
EPwm1Regs.TBPRD = LLC_PRD;
EPwm1Regs.CMPA.bit.CMPA = LLC_PRD;
EPwm1Regs.CMPB.bit.CMPB = LLC_PRD;
EPwm1Regs.CMPA.bit.CMPAHR = (1 << 8);
EPwm1Regs.CMPB.bit.CMPBHR = (1 << 8);
EPwm1Regs.CMPC = 0;
EPwm1Regs.CMPD = 0;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL2.bit.SHDWCMODE = CC_IMMEDIATE;
EPwm1Regs.CMPCTL2.bit.SHDWDMODE = CC_IMMEDIATE;
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CBD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
EPwm1Regs.AQSFRC.bit.RLDCSF = 3;
EPwm1Regs.DBCTL.bit.HALFCYCLE = 1;
EPwm1Regs.DBCTL.bit.OUTSWAP = 3;
EPwm1Regs.DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm1Regs.DBCTL.bit.SHDWDBREDMODE = 1;
EPwm1Regs.DBCTL.bit.LOADREDMODE = 1;
EPwm1Regs.DBCTL.bit.SHDWDBFEDMODE = 1;
EPwm1Regs.DBCTL.bit.LOADFEDMODE = 1;
EPwm1Regs.DBRED.bit.DBRED = 20;
EPwm1Regs.DBFED.bit.DBFED = 20;
EPwm1Regs.AQCSFRC.bit.CSFA = 1;
EPwm1Regs.AQCSFRC.bit.CSFB = 2;
EALLOW;
EPwm1Regs.HRCNFG.all = 0x0;
EPwm1Regs.HRCNFG.bit.EDGMODE = HR_BEP;
EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP;
EPwm1Regs.HRCNFG.bit.HRLOAD = CC_CTR_ZERO;
EPwm1Regs.HRCNFG.bit.EDGMODEB = HR_BEP;
EPwm1Regs.HRCNFG.bit.CTLMODEB = HR_CMP;
EPwm1Regs.HRCNFG.bit.HRLOADB = CC_CTR_ZERO;
EPwm1Regs.HRCNFG.bit.AUTOCONV = 1;
EPwm1Regs.HRCNFG.bit.SWAPAB = 0;
EPwm1Regs.HRCNFG2.bit.EDGMODEDB = 3;
EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
EPwm1Regs.HRPCTL.bit.HRPE = 1;
EDIS;
EALLOW;
EPwm1Regs.GLDCTL.bit.OSHTMODE =1;
EPwm1Regs.GLDCTL.bit.GLDMODE = 0;
EPwm1Regs.GLDCTL.bit.GLD = 1;
EPwm1Regs.GLDCFG.all =0x001F;
EPwm1Regs.EPWMXLINK.bit.GLDCTL2LINK = 0;
EPwm1Regs.GLDCTL2.bit.OSHTLD =1;
EPwm1Regs.AQSFRC.bit.RLDCSF = 0;
EDIS;
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm2Regs.TBCTL.bit.SYNCOSEL = 0;
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.PHSDIR = 1;
EPwm2Regs.TBCTL2.bit.PRDLDSYNC = 0;
EPwm2Regs.TBPHS.bit.TBPHS = 0;
EPwm2Regs.TBCTR = 0;
EPwm2Regs.TBPRD = LLC_PRD;
EPwm2Regs.CMPA.bit.CMPA = LLC_PRD;
EPwm2Regs.CMPB.bit.CMPB = LLC_PRD;
EPwm2Regs.CMPA.bit.CMPAHR = (1 << 8);
EPwm2Regs.CMPB.bit.CMPBHR = (1 << 8);
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.AQCTLA.bit.CBU = AQ_SET;
EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm2Regs.AQCTLB.bit.CAD = AQ_CLEAR;
EPwm2Regs.AQSFRC.bit.RLDCSF = 3;
EPwm2Regs.DBCTL.bit.HALFCYCLE = 1;
EPwm2Regs.DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm2Regs.DBCTL.bit.OUTSWAP = 0;
EPwm2Regs.DBCTL.bit.SHDWDBREDMODE = 1;
EPwm2Regs.DBCTL.bit.LOADREDMODE = 1;
EPwm2Regs.DBCTL.bit.SHDWDBFEDMODE = 1;
EPwm2Regs.DBCTL.bit.LOADFEDMODE = 1;
EPwm2Regs.DBRED.bit.DBRED = 20;
EPwm2Regs.DBFED.bit.DBFED = 20;
EPwm2Regs.AQCSFRC.bit.CSFA = 1;
EPwm2Regs.AQCSFRC.bit.CSFB = 2;
EALLOW;
EPwm2Regs.HRCNFG.all = 0x0;
EPwm2Regs.HRCNFG.bit.EDGMODE = HR_BEP;
EPwm2Regs.HRCNFG.bit.CTLMODE = HR_CMP;
EPwm2Regs.HRCNFG.bit.HRLOAD = CC_CTR_ZERO;
EPwm2Regs.HRCNFG.bit.EDGMODEB = HR_BEP;
EPwm2Regs.HRCNFG.bit.CTLMODEB = HR_CMP;
EPwm2Regs.HRCNFG.bit.HRLOADB = CC_CTR_ZERO;
EPwm2Regs.HRCNFG.bit.AUTOCONV = 1;
EPwm2Regs.HRCNFG.bit.SWAPAB = 0;
EPwm2Regs.HRCNFG2.bit.EDGMODEDB = 3;
EPwm2Regs.HRPCTL.bit.TBPHSHRLOADE = 1;
EPwm2Regs.HRPCTL.bit.HRPE = 1; /
EDIS;
EALLOW;
EPwm2Regs.EPWMXLINK.bit.TBPRDLINK = 0;
EPwm2Regs.EPWMXLINK.bit.CMPALINK = 0;
EPwm2Regs.EPWMXLINK.bit.CMPBLINK = 0;
EPwm2Regs.GLDCTL.bit.OSHTMODE =1;
EPwm2Regs.GLDCTL.bit.GLDMODE = 0;
EPwm2Regs.GLDCTL.bit.GLD = 1;
EPwm2Regs.GLDCFG.all =0x001F;
EPwm2Regs.EPWMXLINK.bit.GLDCTL2LINK = 0;
EPwm2Regs.GLDCTL2.bit.OSHTLD =1;
EPwm2Regs.AQSFRC.bit.RLDCSF = 0;
EDIS;
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EPwm1Regs.TBCTL.bit.SWFSYNC = 1;
EPwm2Regs.TBCTL.bit.SWFSYNC = 1;
EDIS;
update PWM in 20k ISR
LLCDuty_HR = (Uint16) ((0.4)*65536);
fLLCPrd = 50000/fLLCFreq + 0.5f;
LLCPrd = (Uint16)(fLLCPrd);
LLCPrd_HR = (Uint16)((fLLCPrd-LLCPrd)*65536);
EPwm1Regs.TBPRD = LLCPrd;
EPwm1Regs.TBPRDHR =LLCPrd_HR;
EPwm1Regs.CMPA.bit.CMPA = LLCPrd/2-LLCDuty;
EPwm1Regs.CMPA.bit.CMPAHR =65536-LLCDuty_HR ;
EPwm1Regs.CMPB.bit.CMPB = LLCPrd/2+LLCDuty;
EPwm1Regs.CMPB.bit.CMPBHR = LLCDuty_HR ;
if(EPwm1Regs.TBCTR > 80)
{
GpioDataRegs.GPBSET.bit.GPIO59 = 1;
EPwm1Regs.GLDCTL2.bit.OSHTLD =1;
GpioDataRegs.GPBCLEAR.bit.GPIO59 = 1;
}
else
{
GpioDataRegs.GPBSET.bit.GPIO59 = 1;
for(delay_n=0;delay_n<9;)
delay_n++;
EPwm1Regs.GLDCTL2.bit.OSHTLD =1;
GpioDataRegs.GPBCLEAR.bit.GPIO59 = 1;
}
Best regards
Does disabling the synchronization eliminate the wrong first cycle output?
Nima
EPwm1Regs.TBCTL.bit.SYNCOSEL =TB_SYNC_DISABLE can eliminate the wrong first cycle output.
but out of synchronization with phase difference:
And waveform is the same when
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN or EPwm2Regs.TBCTL.bit.SYNCOSEL = 3TB_SYNC_DISABLE
How to disable the synchronization
By Deleting EPWMXLINK code shows as follow?
EPwm2Regs.EPWMXLINK.bit.TBPRDLINK = 0;
EPwm2Regs.EPWMXLINK.bit.CMPALINK = 0;
EPwm2Regs.EPWMXLINK.bit.CMPBLINK = 0;EPwm2Regs.EPWMXLINK.bit.GLDCTL2LINK = 0;
deleting EPwm2Regs.EPWMXLINK.bit.GLDCTL2LINK = 0 or EPwm2Regs.EPWMXLINK.bit.GLDCTL2LINK =1 ,and adding EPwm2Regs.GLDCTL2.bit.OSHTLD =1 to update PWM2. The phenomenon is the same
EALLOW;
EPwm2Regs.EPWMXLINK.bit.TBPRDLINK = 0;
EPwm2Regs.EPWMXLINK.bit.CMPALINK = 0;
EPwm2Regs.EPWMXLINK.bit.CMPBLINK = 0;
EPwm2Regs.GLDCTL.bit.OSHTMODE =1;
EPwm2Regs.GLDCTL.bit.GLDMODE = 0;
EPwm2Regs.GLDCTL.bit.GLD = 1;
EPwm2Regs.GLDCFG.all =0x001F;
//EPwm2Regs.EPWMXLINK.bit.GLDCTL2LINK = 0; //delete
EPwm2Regs.GLDCTL2.bit.OSHTLD =1;
EPwm2Regs.AQSFRC.bit.RLDCSF = 0;
EDIS;
EALLOW;
if(EPwm1Regs.TBCTR > 80)
{
GpioDataRegs.GPBSET.bit.GPIO59 = 1;
EPwm1Regs.GLDCTL2.bit.OSHTLD =1;
EPwm2Regs.GLDCTL2.bit.OSHTLD =1; // add
GpioDataRegs.GPBCLEAR.bit.GPIO59 = 1;
}
else
{
GpioDataRegs.GPBSET.bit.GPIO59 = 1;
for(delay_n=0;delay_n<9;)
delay_n++;
EPwm1Regs.GLDCTL2.bit.OSHTLD =1;
EPwm2Regs.GLDCTL2.bit.OSHTLD =1; // add
GpioDataRegs.GPBCLEAR.bit.GPIO59 = 1;
}
dear Nima
Deleting the following two lines of code can eliminate the wrong first cycle output.
EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 1; //delete
EPwm2Regs.HRPCTL.bit.TBPHSHRLOADE = 1;//delete
But high resolution duty control can not work When EPwm1Regs.TBPRDHR and EPwm1Regs.TBPRD are a fixed value.
EPwm1Regs.CMPA.bit.CMPAHR = 0,the duty of PWM1 is equal to 48.2%
And EPwm1Regs.CMPA.bit.CMPAHR = 0xff00,the duty of PWM1 is still equal to 48.2%
EPwm1Regs.CMPA.bit.CMPA =208;
EPwm1Regs.CMPA.bit.CMPAHR = 0xff00;
EPwm1Regs.CMPB.bit.CMPB = 208;
EPwm1Regs.CMPB.bit.CMPBHR = 0;
it is not possible to use both edges controlled by CMPA and CMPB events?
What you can do is in HR mode use CHANNEL A, with CMPA events (CMPAU CMPAD)
Use Channel B with CMPB events (CMPBU CMPBD)
You dont want to use CMPA and CMPB on the same channel.
I am going to close this for now. If you have a question that I failed to answer please reply with that specifically below.
Going over your thread again, I didnt think this was a global load issue.
EPwm2Regs.EPWMXLINK.bit.GLDCTL2LINK = 0 or EPwm2Regs.EPWMXLINK.bit.GLDCTL2LINK =1 should not affect the output.
You mentioned:
"Deleting the following two lines of code can eliminate the wrong first cycle output.
EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 1; //delete
EPwm2Regs.HRPCTL.bit.TBPHSHRLOADE = 1;//delete"
That would possibly be the issue as you are not using HR phase shift, since you are already using HR period and HR duty.
Finally,
"EPwm1Regs.CMPA.bit.CMPAHR = 0,the duty of PWM1 is equal to 48.2%
And EPwm1Regs.CMPA.bit.CMPAHR = 0xff00,the duty of PWM1 is still equal to 48.2%
EPwm1Regs.CMPA.bit.CMPA =208;
EPwm1Regs.CMPA.bit.CMPAHR = 0xff00;
EPwm1Regs.CMPB.bit.CMPB = 208;
EPwm1Regs.CMPB.bit.CMPBHR = 0;"
Well to answer your first part about the duty being the same when CMPAHR equals 0 or 0xFF00, that is as expected. In fact the value of ZERO is not an acceptable value, if you try to single step over code with sets the value of CMPAHR from 0 to CMPAHR to 0x0100, you will see a big jump. and the duty calculation for CMPAHR = 0 is incorrect. CMPAHR = 0 will give the same result as CMPAHR=0xFF00.
That is why in the next revision of HRPWM code which I will release, I have the following switch in the code:
float32_t count = ((100.0 - dutyFine) * (float32_t)(EPWM_TIMER_TBPRD << 8))/100.0; uint32_t compCount = (count); uint32_t hrCompCount = (compCount & (0x000000FF)); if (hrCompCount == 0) { // // Add 1 to not have CMPxHR = 0 // compCount |= 0x00000001; } HRPWM_setCounterCompareValue(ePWM[i], HRPWM_COUNTER_COMPARE_A, compCount);