Part Number:TMS320F28379S
本设计使用了四个EPWM模块(EPWM1\EPWM2\EPWM4\EPWM6),其中EPWM1不使用其输出的PWM波形,只是作为EPWM2\4\6的时基信号,其中EPWM2\4\6配置使用了global load,并利用EPWMXLINK将EPWM4\6都链接到了EPWM2的global load装载上。但实际应用中发现会在几个周期内出现某一次漏装载现象。
从下图可看到漏装载的是周期值(但我代码里周期值和计数器值都是计算完一起全局装载的),它会在数个50Hz周期内偶然出现一次漏装载现象(计数器装载了,但周期值却没装进去),全局装载并没有很完美的工作
以下两图是其它周期的正常装载现象
Yale Li:
泡瓦伊莱克 说:它会在数个50Hz周期内偶然出现一次漏装载现象
这个50Hz是指什么呀?
,
泡瓦伊莱克:
Li工您好,50Hz是我从0-2pi所有控制周期完成的值,其中控制周期为10微秒(而所有global load使能的寄存器也是10微秒全部装载一次)
,
Yale Li:
这个问题的复现几率如何?
,
泡瓦伊莱克:
大概是每5-8个50Hz周期,其中一个周期内的某一个10微秒控制周期会出现一次漏装载现象,经检查无规律,所以认为不是代码问题,百思不得其解,很困扰
,
泡瓦伊莱克:
因为我电感非常小(几μH级),所以一个10微秒的漏装载导致的误发波会出现非常大的电流尖峰
,
Yale Li:
我想确定一下的是,在几个片子上遇到了这个问题。如果是成批量出现的,我会去问一下相关的工程师。另外你的器件是在哪里买的?
,
泡瓦伊莱克:
呃两个片子都出现了同样的情况,因为我是高校研究人员不是企业,所以没有批量化测试的条件。器件是在TI官网上买的,两年前买的芯片了
,
Yale Li:
能否再进一步说明一下,你的PWM的周期大概是多少?配置的是在什么时刻进行全局装载?
泡瓦伊莱克 说:其中EPWM1不使用其输出的PWM波形,只是作为EPWM2\4\6的时基信号
这个能否再解释一下?你的意思是不是EPWM2\4\6是以EPWM1为基准进行同步移相的?
,
泡瓦伊莱克:
PWM周期最低也是100kHz以上,控制的话是配置的10微秒的中断控制,在中断服务函数的最后(所有寄存器值已经全部重新更新了):
配置代码:
EALLOW;EPwm2Regs.GLDCTL2.bit.OSHTLD=1;EDIS;
这就意味着EPWM2\4\6全部都一次性装载完了
,
泡瓦伊莱克:
EPWM2、4、6仅仅与EPWM1的时间基准保持同步,
EPWM1时间基准代码: EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
EPWM2\4\6时间基准代码:
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
没有使用移相模块
,
Yale Li:
方便把相关的代码发上来吗?
,
泡瓦伊莱克:
void InitEPwm1Example() {EPwm1Regs.TBPRD = 1000;// Set timer periodEPwm1Regs.TBPHS.bit.TBPHS = 0x0000;// Phase is 0EPwm1Regs.TBCTR = 0x0000;// Clear counter//// Setup TBCLK//EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count upEPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;// Disable phase loadingEPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;// Clock ratio to SYSCLKOUTEPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;// Load registers every ZEROEPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD;EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;// Load registers every ZEROEPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;//// Setup compare//EPwm1Regs.CMPB.bit.CMPB = 600;EPwm1Regs.CMPA.bit.CMPA = 400;// //EPwm6Regs.EPWMXLINK.bit.CMPALINK=0; //EPwm6Regs.EPWMXLINK.bit.TBPRDLINK=0;EPwm1Regs.AQCTL.bit.SHDWAQBMODE = 1;EPwm1Regs.AQCTL.bit.SHDWAQAMODE = 1;EPwm1Regs.AQCTL.bit.LDAQBMODE = CC_CTR_PRD;EPwm1Regs.AQCTL.bit.LDAQAMODE = CC_CTR_PRD;// Set actionsEPwm1Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION;// Set PWM1A on ZeroEPwm1Regs.AQCTLA.bit.CAU = AQ_NO_ACTION;EPwm1Regs.AQCTLA.bit.CBU = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm1Regs.AQCTLB.bit.CBU = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm1Regs.AQCTLB.bit.CAU = AQ_NO_ACTION;EPwm1Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION;// Set PWM1A on ZeroEPwm1Regs.AQCTLB.bit.PRD = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;// Set PWM1A on ZeroEPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;EPwm1Regs.AQCTLB.bit.PRD = AQ_CLEAR;// Set PWM1B on ZeroEPwm1Regs.AQCTLB.bit.CBU = AQ_SET;//// Interrupt where we will change the Deadband// //EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;// Select INT on Zero event //EPwm1Regs.ETSEL.bit.INTEN = 1;// Enable INT //EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;// Generate INT on 3rd event }void InitEPwm2Example() {EPwm2Regs.TBPRD = 1000;// Set timer periodEPwm2Regs.TBPHS.bit.TBPHS = 0x0000;// Phase is 0EPwm2Regs.TBCTR = 0x0000;// Clear counter//// Setup TBCLK//EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count upEPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;// Disable phase loadingEPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;// Clock ratio to SYSCLKOUTEPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;// Load registers every ZEROEPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD;EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;// Load registers every ZEROEPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;//// Setup compare//EPwm2Regs.CMPB.bit.CMPB = 600;EPwm2Regs.CMPA.bit.CMPA = 400;// //EPwm6Regs.EPWMXLINK.bit.CMPALINK=0; //EPwm6Regs.EPWMXLINK.bit.TBPRDLINK=0;EPwm2Regs.AQCTL.bit.SHDWAQBMODE = 1;EPwm2Regs.AQCTL.bit.SHDWAQAMODE = 1;EPwm2Regs.AQCTL.bit.LDAQBMODE = CC_CTR_PRD;EPwm2Regs.AQCTL.bit.LDAQAMODE = CC_CTR_PRD;// Set actionsEPwm2Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION;// Set PWM1A on ZeroEPwm2Regs.AQCTLA.bit.CAU = AQ_NO_ACTION;EPwm2Regs.AQCTLA.bit.CBU = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm2Regs.AQCTLB.bit.CBU = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm2Regs.AQCTLB.bit.CAU = AQ_NO_ACTION;EPwm2Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION;// Set PWM1A on ZeroEPwm2Regs.AQCTLB.bit.PRD = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;// Set PWM1A on ZeroEPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR;// Set PWM1B on ZeroEPwm2Regs.AQCTLB.bit.CBU = AQ_SET;///*死区时间配置*/////Setup Deadband//EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HI;//目标:EPWMA,EPWMB都单独在上升沿统一延时一定量的死区时间,实现不了EPwm2Regs.DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;EPwm2Regs.DBCTL.bit.OUTSWAP = 0x0;EPwm2Regs.DBCTL.bit.DEDB_MODE = 0;EPwm2Regs.DBCTL.bit.SHDWDBFEDMODE= 1;EPwm2Regs.DBCTL.bit.SHDWDBREDMODE = 1;EPwm2Regs.DBCTL.bit.LOADREDMODE = 0x01;EPwm2Regs.DBCTL.bit.LOADFEDMODE = 0x01;EPwm2Regs.DBCTL2.bit.SHDWDBCTLMODE = 1;EPwm2Regs.DBCTL2.bit.LOADDBCTLMODE = 0x01;EPwm2Regs.DBRED.bit.DBRED = DeadBand;EPwm2Regs.DBFED.bit.DBFED = DeadBand;////设置global load寄存器EALLOW;EPwm2Regs.GLDCTL.bit.GLDMODE=1;//load on periodEPwm2Regs.GLDCTL.bit.OSHTMODE=1;EPwm2Regs.GLDCTL.bit.GLD=1;//active as GLDMODE bitsEPwm2Regs.GLDCFG.bit.AQCTLA_AQCTLA2=1;EPwm2Regs.GLDCFG.bit.AQCTLB_AQCTLB2=1;EPwm2Regs.GLDCFG.bit.CMPA_CMPAHR=1;EPwm2Regs.GLDCFG.bit.CMPB_CMPBHR=1;EPwm2Regs.GLDCFG.bit.TBPRD_TBPRDHR=1;EPwm2Regs.GLDCFG.bit.DBCTL=1;EPwm2Regs.GLDCFG.bit.DBFED_DBFEDHR =1;EPwm2Regs.GLDCFG.bit.DBRED_DBREDHR =1;EDIS;//// Interrupt where we will change the Deadband////EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;// Select INT on Zero event//EPwm6Regs.ETSEL.bit.INTEN = 1;// Enable INT//EPwm6Regs.ETPS.bit.INTPRD = ET_1ST;// Generate INT on 3rd event }void InitEPwm4Example() {EPwm4Regs.TBPRD = 1000;// Set timer periodEPwm4Regs.TBPHS.bit.TBPHS = 0x0000;// Phase is 0EPwm4Regs.TBCTR = 0x0000;// Clear counter//// Setup TBCLK//EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count upEPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE;// Disable phase loadingEPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;// Clock ratio to SYSCLKOUTEPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;// Load registers every ZEROEPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD;EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;// Load registers every ZEROEPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;//// Setup compare//EPwm4Regs.CMPB.bit.CMPB = 600;EPwm4Regs.CMPA.bit.CMPA = 400;// //EPwm6Regs.EPWMXLINK.bit.CMPALINK=0; //EPwm6Regs.EPWMXLINK.bit.TBPRDLINK=0;EPwm4Regs.AQCTL.bit.SHDWAQBMODE = 1;EPwm4Regs.AQCTL.bit.SHDWAQAMODE = 1;EPwm4Regs.AQCTL.bit.LDAQBMODE = CC_CTR_PRD;EPwm4Regs.AQCTL.bit.LDAQAMODE = CC_CTR_PRD;// Set actionsEPwm4Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION;// Set PWM1A on ZeroEPwm4Regs.AQCTLA.bit.CAU = AQ_NO_ACTION;EPwm4Regs.AQCTLA.bit.CBU = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm4Regs.AQCTLB.bit.CBU = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm4Regs.AQCTLB.bit.CAU = AQ_NO_ACTION;EPwm4Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION;// Set PWM1A on ZeroEPwm4Regs.AQCTLB.bit.PRD = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm4Regs.AQCTLA.bit.ZRO = AQ_SET;// Set PWM1A on ZeroEPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR;EPwm4Regs.AQCTLB.bit.PRD = AQ_CLEAR;// Set PWM1B on ZeroEPwm4Regs.AQCTLB.bit.CBU = AQ_SET;///*死区时间配置*/////Setup Deadband//EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HI;//目标:EPWMA,EPWMB都单独在上升沿统一延时一定量的死区时间,实现不了EPwm4Regs.DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;EPwm4Regs.DBCTL.bit.OUTSWAP = 0x0;EPwm4Regs.DBCTL.bit.DEDB_MODE = 0;EPwm4Regs.DBCTL.bit.SHDWDBFEDMODE= 1;EPwm4Regs.DBCTL.bit.SHDWDBREDMODE = 1;EPwm4Regs.DBCTL.bit.LOADREDMODE = 0x01;EPwm4Regs.DBCTL.bit.LOADFEDMODE = 0x01;EPwm4Regs.DBCTL2.bit.SHDWDBCTLMODE = 1;EPwm4Regs.DBCTL2.bit.LOADDBCTLMODE = 0x01;EPwm4Regs.DBRED.bit.DBRED = DeadBand;EPwm4Regs.DBFED.bit.DBFED = DeadBand;////设置global load寄存器EALLOW;EPwm4Regs.GLDCTL.bit.GLDMODE=1;//load on periodEPwm4Regs.GLDCTL.bit.OSHTMODE=1;EPwm4Regs.GLDCTL.bit.GLD=1;//active as GLDMODE bitsEPwm4Regs.GLDCFG.bit.AQCTLA_AQCTLA2=1;EPwm4Regs.GLDCFG.bit.AQCTLB_AQCTLB2=1;EPwm4Regs.GLDCFG.bit.CMPA_CMPAHR=1;EPwm4Regs.GLDCFG.bit.CMPB_CMPBHR=1;EPwm4Regs.GLDCFG.bit.TBPRD_TBPRDHR=1;EPwm4Regs.GLDCFG.bit.DBCTL=1;EPwm4Regs.GLDCFG.bit.DBFED_DBFEDHR =1;EPwm4Regs.GLDCFG.bit.DBRED_DBREDHR =1;EDIS;EPwm4Regs.EPWMXLINK.bit.GLDCTL2LINK=1;//// Interrupt where we will change the Deadband// //EPwm4Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;// Select INT on Zero event //EPwm4Regs.ETSEL.bit.INTEN = 1;// Enable INT //EPwm4Regs.ETPS.bit.INTPRD = ET_1ST;// Generate INT on 3rd event }void InitEPwm6Example() {EPwm6Regs.TBPRD = 1000;// Set timer periodEPwm6Regs.TBPHS.bit.TBPHS = 0x0000;// Phase is 0EPwm6Regs.TBCTR = 0x0000;// Clear counter//// Setup TBCLK//EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count upEPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;// Disable phase loadingEPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;// Clock ratio to SYSCLKOUTEPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1;EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;// Load registers every ZEROEPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD;EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;// Load registers every ZEROEPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;//// Setup compare//EPwm6Regs.CMPB.bit.CMPB = 600;EPwm6Regs.CMPA.bit.CMPA = 400;// //EPwm6Regs.EPWMXLINK.bit.CMPALINK=0; //EPwm6Regs.EPWMXLINK.bit.TBPRDLINK=0;EPwm6Regs.AQCTL.bit.SHDWAQBMODE = 1;EPwm6Regs.AQCTL.bit.SHDWAQAMODE = 1;EPwm6Regs.AQCTL.bit.LDAQBMODE = CC_CTR_PRD;EPwm6Regs.AQCTL.bit.LDAQAMODE = CC_CTR_PRD;// Set actionsEPwm6Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION;// Set PWM1A on ZeroEPwm6Regs.AQCTLA.bit.CAU = AQ_NO_ACTION;EPwm6Regs.AQCTLA.bit.CBU = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm6Regs.AQCTLB.bit.CBU = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm6Regs.AQCTLB.bit.CAU = AQ_NO_ACTION;EPwm6Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION;// Set PWM1A on ZeroEPwm6Regs.AQCTLB.bit.PRD = AQ_NO_ACTION;// Set PWM1B on ZeroEPwm6Regs.AQCTLA.bit.ZRO = AQ_SET;// Set PWM1A on ZeroEPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR;EPwm6Regs.AQCTLB.bit.PRD = AQ_CLEAR;// Set PWM1B on ZeroEPwm6Regs.AQCTLB.bit.CBU = AQ_SET;///*死区时间配置*/////Setup Deadband//EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HI;//目标:EPWMA,EPWMB都单独在上升沿统一延时一定量的死区时间,实现不了EPwm6Regs.DBCTL.bit.IN_MODE = DBA_RED_DBB_FED;EPwm6Regs.DBCTL.bit.OUTSWAP = 0x0;EPwm6Regs.DBCTL.bit.DEDB_MODE = 0;EPwm6Regs.DBCTL.bit.SHDWDBFEDMODE= 1;EPwm6Regs.DBCTL.bit.SHDWDBREDMODE = 1;EPwm6Regs.DBCTL.bit.LOADREDMODE = 0x01;EPwm6Regs.DBCTL.bit.LOADFEDMODE = 0x01;EPwm6Regs.DBCTL2.bit.SHDWDBCTLMODE = 1;EPwm6Regs.DBCTL2.bit.LOADDBCTLMODE = 0x01;EPwm6Regs.DBRED.bit.DBRED = DeadBand;EPwm6Regs.DBFED.bit.DBFED = DeadBand;//if(mode==1) //{ ///*TCM下死区时间配置*/ //// //// Active Low PWMs - Setup Deadband //// //EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // //EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;//EPWMB反相 // //EPwm6Regs.DBCTL.bit.IN_MODE = DBA_ALL; // //EPwm6Regs.DBRED.bit.DBRED = DeadBand; //EPwm6Regs.DBFED.bit.DBFED = DeadBand; // //} //else //{ /////*DCM下死区时间配置*/ ////// ////// Active Low PWMs - Setup Deadband ////// // //EPwm6Regs.DBCTL.bit.OUT_MODE = DB_DISABLE; // //// ////EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HI; //// ////EPwm6Regs.DBCTL.bit.IN_MODE = DBA_RED_DBB_FED; //// ////EPwm6Regs.DBRED.bit.DBRED = DeadBand; ////EPwm6Regs.DBFED.bit.DBFED = DeadBand; //}////设置global load寄存器EALLOW;EPwm6Regs.GLDCTL.bit.GLDMODE=1;//load on periodEPwm6Regs.GLDCTL.bit.OSHTMODE=1;EPwm6Regs.GLDCTL.bit.GLD=1;//active as GLDMODE bitsEPwm6Regs.GLDCFG.bit.AQCTLA_AQCTLA2=1;EPwm6Regs.GLDCFG.bit.AQCTLB_AQCTLB2=1;EPwm6Regs.GLDCFG.bit.CMPA_CMPAHR=1;EPwm6Regs.GLDCFG.bit.CMPB_CMPBHR=1;EPwm6Regs.GLDCFG.bit.TBPRD_TBPRDHR=1;EPwm6Regs.GLDCFG.bit.DBCTL=1;EPwm6Regs.GLDCFG.bit.DBFED_DBFEDHR =1;EPwm6Regs.GLDCFG.bit.DBRED_DBREDHR =1;EDIS;EPwm6Regs.EPWMXLINK.bit.GLDCTL2LINK=1;//// Interrupt where we will change the Deadband////EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;// Select INT on Zero event//EPwm6Regs.ETSEL.bit.INTEN = 1;// Enable INT//EPwm6Regs.ETPS.bit.INTPRD = ET_1ST;// Generate INT on 3rd event }
,
泡瓦伊莱克:
这是EPWM配置的代码
,
泡瓦伊莱克:
EALLOW;EPwm2Regs.GLDCTL2.bit.OSHTLD=1; //EPwm4Regs.GLDCTL2.bit.OSHTLD=1; //EPwm6Regs.GLDCTL2.bit.OSHTLD=1;EDIS;这是global load全局装载的代码,在所有受影响的EPWM寄存器赋值完的最后执行