由于电路设计的需求,需要在电流过零点产生一个脉冲信号去同步PWM2的信号,目前使用Ecap功能去捕获这个脉冲信号,然后在ecap中断中将TBCTL.SWFSYNC写1,清零PWM的计数器,正常的波形应该是如下图所示,可以看到CH1(黄色)和CH2(红色)是PWM2B和PWM2A的信号,占空比目前固定分别为0.8和0.2左右,开关频率1MHz,系统时钟周期配置为200MHz, CH4是我ecap中断函数运行时对GPIO口进行翻转,在ecap捕获到该脉冲的开关周期内,将计数器清零,PWM2B(黄色)由于计数器被清零导致导通时间变长,但其他开关周期内导通时间不变。
但现在的问题是一段时间内在ecap触发之后的几个周期内,即使没有脉冲触发eCAP,发现在有的开关周期内PWM导通时间也会变化,如下图所示,
如果不去对TBCTL.SWFSYNC写1,发现PWM都没有变换可以排除是PWM2B和PWM2A由于比较值的变化带来的导通时间的变换,所以问题应该还是出在同步上。PWM配置和eCap程序如下:
void Epwm_Init(void)
{
ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 0;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EPwm2Regs.TBPRD = (Uint16)(TLBDC_PER); //PWM period
EPwm2Regs.TBPHS.bit.TBPHS = 0;//TLBDC_PHASE(120.0f);//0; //No phase shift
EPwm2Regs.TBCTL.bit.FREE_SOFT = 2; //Free run
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1; //System clock out / 1
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; //System clock out / 1
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;//TB_CTR_ZERO;//TB_SYNC_IN;//TB_CTR_ZERO; //Send synchronization signal when counter = 0
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW; //Using shadow register for PWM period
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;//TB_DISABLE;//TB_DISABLE; //Master, don't need load phase register
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;//TB_COUNT_UPDOWN; //TB_COUNT_UP;//Up-down mode
EPwm2Regs.CMPA.bit.CMPA = TLBDC_CMPA(0);//TLBDC_CMPA(0.3);//cmpa=zkb*prd(s1),zkb=pi_out
EPwm2Regs.CMPB.bit.CMPB = TLBDC_CMPB(0);//TLBDC_CMPB(0.3);//phase=180; zkb'=pi_out,cmpb=(1-zkb')*prd=(1-pi_out)*prd (s2,pass a not logic->s3)
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_IMMEDIATE;//CC_SHADOW;//Using shadow register for compare
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_IMMEDIATE;//CC_SHADOW;//Using shadow register for compare
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD;//Load new compare value when counter = period
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD;//CC_CTR_ZERO;//Load new compare value when counter = zero
EPwm2Regs.AQCTLA.bit.ZRO = AQ_CLEAR;//AQ_SET; // Set PWM1A on Zero
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; //AQ_CLEAR; // Clear PWM1A on event A,
// up count
EPwm2Regs.AQCTLB.bit.ZRO = AQ_SET; // Set PWM1B on Zero
EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Clear PWM1B on event B,
EPwm2Regs.DBCTL.bit.IN_MODE = DBB_RED_DBA_FED;//DBA_RED_DBB_FED;//s5=1,s4=0
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;//DBB_ENABLE;//DB_DISABLE;//DBB_ENABLE;// s1=0,s0=1(Q3)->0(Q2)
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HI;//DB_ACTV_LO;//0x00;//DB_ACTV_HIC;// s3=1,s2=0->1, Active Hi complementary
EPwm2Regs.DBFED = 0x00;//INV_DEAD_CYCLE;// FED = INV_DEAD_CYCLE TBCLKs
EPwm2Regs.DBRED = 0x0a;//INV_DEAD_CYCLE;// RED = INV_DEAD_CYCLE TBCLKs
EPwm2Regs.DBCTL.bit.OUTSWAP = 0x03;
//add soca
EPwm2Regs.ETSEL.bit.SOCAEN=ET_ENABLE;//enable
EPwm2Regs.ETSEL.bit.SOCASEL=ET_CTR_PRDZERO;//ET_CTR_PRDZERO;
EPwm2Regs.ETPS.bit.SOCAPRD=ET_1ST;//divide frequency, page69/117.
//1 1 2 3-Generate the EPWMxSOCA pulse on the first second third event:
//2 Once the SOCA pulse is generated, the ETPS[SOCACNT] bits will automatically be cleared.
EPwm2Regs.ETSEL.bit.SOCBEN=ET_ENABLE;//enable
EPwm2Regs.ETSEL.bit.SOCBSEL=ET_CTR_PRDZERO;//ET_CTR_ZERO;
EPwm2Regs.ETPS.bit.SOCBPRD=ET_1ST;//divide frequency
//3 Generate the EPWMxSOCA pulse on the first event: ETPS[SOCACNT] = 0,1
EPwm2Regs.ETSEL.bit.INTEN=ET_DISABLE;
EPwm2Regs.ETPS.bit.INTPRD=ET_DISABLE;
EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
EPwm2Regs.TZFRC.bit.OST = 1;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
}
interrupt void ecap1_isr(void)
{
static Uint16 Freq_temp_pre = 0, Freq_temp_cnt = 0, Freq_temp = 0;
EALLOW;
GpioDataRegs.GPASET.bit.GPIO12 = 1;
EDIS;
EPwm2Regs.TBCTL.bit.SWFSYNC = 1;
ECap1Regs.ECCLR.bit.CEVT1 = 1;
ECap1Regs.ECCLR.bit.INT = 1;
ECap1Regs.ECCTL2.bit.REARM = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
GpioDataRegs.GPACLEAR.bit.GPIO12 = 1;
}
1.请问我这种软件同步有什么问题吗?
2.如果不用软件同步,采用外部硬件同步的话,是将EPWM2SYNCI和我的GPIO通过inputXBAR相关联吗?
3.除了用ecap来捕捉这个脉冲外,如何采用trip zone +digital compare 来捕捉这个外部的脉冲信号?
mangui zhang:参考一下相关的帖子使用硬件同步试试
e2echina.ti.com/…/66261