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.
Hi TI 工程师,
我们在使用DSP28035过程中发现, CSFA/CSFB使能DPWM时会出现漏波的情况,请问漏波的原理是什么,我们如何解决这个问题?
下面的代码是CSFA/CSFB的控制,出现的现象如下图(波形为1B与2B);
if((gVolt_Out>>gVolt_Convert) <= (PERIOD+1))
{
gFreq_Burst_Flag = 1;
EALLOW;
EPwm1Regs.AQCSFRC.bit.CSFA = EPWM_LOW;
EPwm1Regs.AQCSFRC.bit.CSFB = EPWM_LOW;
EPwm2Regs.AQCSFRC.bit.CSFA = EPWM_LOW;
EPwm2Regs.AQCSFRC.bit.CSFB = EPWM_LOW;
EDIS;
}
if(((gVolt_Out>>gVolt_Convert) > (PERIOD+2))&&(gFreq_Burst_Flag == 1))
{
gFreq_Burst_Flag = 0;
EALLOW;
EPwm1Regs.AQCSFRC.bit.CSFA = EPWM_ENABLE;
EPwm1Regs.AQCSFRC.bit.CSFB = EPWM_ENABLE;
EPwm2Regs.AQCSFRC.bit.CSFA = EPWM_ENABLE;
EPwm2Regs.AQCSFRC.bit.CSFB = EPWM_ENABLE;
EDIS;
}
在开关驱动时,都有可能出现先使能与后使能不同步的情况,并且1A/2A、1B/2B都可能出现。
程序中PWM的初始配置如下;
void InitEPwm1()
{
EPwm1Regs.AQCSFRC.bit.CSFA = EPWM_LOW;
EPwm1Regs.AQCSFRC.bit.CSFB = EPWM_LOW;
EALLOW;
EPwm1Regs.TBPRD = gPeriod_Value/2; // 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/down
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;
// Setup compare
EPwm1Regs.CMPA.half.CMPA = gPeriod_Value/2 - gDeadTime_Value1;
EPwm1Regs.CMPB = gDeadTime_Value1;
// Set action
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.PRD = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//****************************************************************************************
//TZ部分,用COMP1触发,用来做逐波限流功能
EPwm1Regs.TZSEL.bit.OSHT2 = 1;
EPwm1Regs.TZSEL.bit.CBC2 = 1;
EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
// Enable TZ interrupt
EPwm1Regs.TZEINT.bit.OST = 1;
/****************************************************************************************/
//AD触发部分
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTRD_CMPA; // Select SOC from from CPMA on PRD//采样方式
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
EPwm1Regs.ETSEL.bit.SOCBEN = 1; // Enable SOC on A group
EPwm1Regs.ETSEL.bit.SOCBSEL = ET_CTRD_CMPA; // Select SOC from from CPMA on PRD//采样方式
EPwm1Regs.ETPS.bit.SOCBPRD = 1; // Generate pulse on 1st event // ET_CTRD_CMPB
EDIS;
}
void InitEPwm2()
{
EPwm2Regs.AQCSFRC.bit.CSFA = EPWM_LOW;
EPwm2Regs.AQCSFRC.bit.CSFB = EPWM_LOW;
EALLOW;
EPwm2Regs.TBPRD = gPeriod_Value/2; // Set timer period
EPwm2Regs.TBPHS.half.TBPHS = 0x0000; // Phase is 0
EPwm2Regs.TBCTR = 0x0000; // Clear counter
// Setup TBCLK
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up/down
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Disable phase loading
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;
// Setup compare
EPwm2Regs.CMPA.half.CMPA = gPeriod_Value/2 - gDeadTime_Value2;
EPwm2Regs.CMPB = gDeadTime_Value2;
// Set actions
EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm2Regs.AQCTLB.bit.PRD = AQ_SET;
EPwm2Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//****************************************************************************************
//TZ部分,用COMP1触发,用来做逐波限流功能(待验证)
EPwm2Regs.TZSEL.bit.OSHT2 = 1;
EPwm2Regs.TZSEL.bit.CBC2 = 1;
if((gVolt_Out>>gVolt_Convert) <= (PERIOD+1)) { gFreq_Burst_Flag = 1; EALLOW; EPwm1Regs.AQCSFRC.bit.CSFA = EPWM_LOW; EPwm1Regs.AQCSFRC.bit.CSFB = EPWM_LOW; EPwm2Regs.AQCSFRC.bit.CSFA = EPWM_LOW; EPwm2Regs.AQCSFRC.bit.CSFB = EPWM_LOW; EDIS; } if(((gVolt_Out>>gVolt_Convert) > (PERIOD+2))&&(gFreq_Burst_Flag == 1)) { gFreq_Burst_Flag = 0; EALLOW; EPwm1Regs.AQCSFRC.bit.CSFA = EPWM_ENABLE; EPwm1Regs.AQCSFRC.bit.CSFB = EPWM_ENABLE; EPwm2Regs.AQCSFRC.bit.CSFA = EPWM_ENABLE; EPwm2Regs.AQCSFRC.bit.CSFB = EPWM_ENABLE; EDIS; }
应该和这个没有关系。
我上面的代码是在完成初始化之后开始运行的,中断时间是100us,每隔几个毫秒就会开关CSFA/CSFB寄存器,在每次开关的时候会有概率出现,并且此时操作PWM开关的只有这段代码。
另外,我在CSFA/CSFB使能前后关闭时钟(代码如下),这个问题能够解决,但会引入新的问题。
if((gVolt_Out>>gVolt_Convert) <= (PERIOD+1)) { gFreq_Burst_Flag = 1; EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; EPwm1Regs.AQCSFRC.bit.CSFA = EPWM_LOW; EPwm1Regs.AQCSFRC.bit.CSFB = EPWM_LOW; EPwm2Regs.AQCSFRC.bit.CSFA = EPWM_LOW; EPwm2Regs.AQCSFRC.bit.CSFB = EPWM_LOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; } if(((gVolt_Out>>gVolt_Convert) > (PERIOD+2))&&(gFreq_Burst_Flag == 1)) { gFreq_Burst_Flag = 0; EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; EPwm1Regs.AQCSFRC.bit.CSFA = EPWM_ENABLE; EPwm1Regs.AQCSFRC.bit.CSFB = EPWM_ENABLE; EPwm2Regs.AQCSFRC.bit.CSFA = EPWM_ENABLE; EPwm2Regs.AQCSFRC.bit.CSFB = EPWM_ENABLE; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; EDIS; }
你好,我就你的问题与我们这边的同事交流了一下,大致上也没有检查出问题所在。所以为了更有效解决你的问题,我建议将帖子发布到英文E2E论坛上问一下,英文论坛有更资深的FAE和BU可以为你提供支持:
https://e2e.ti.com/support/microcontrollers/c2000/f/c2000-microcontrollers-forum