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.
本设计使用了四个EPWM模块(EPWM1\EPWM2\EPWM4\EPWM6),其中EPWM1不使用其输出的PWM波形,只是作为EPWM2\4\6的时基信号,其中EPWM2\4\6配置使用了global load,并利用EPWMXLINK将EPWM4\6都链接到了EPWM2的global load装载上。但实际应用中发现会在几个周期内出现某一次漏装载现象。
从下图可看到漏装载的是周期值(但我代码里周期值和计数器值都是计算完一起全局装载的),它会在数个50Hz周期内偶然出现一次漏装载现象(计数器装载了,但周期值却没装进去),全局装载并没有很完美的工作
以下两图是其它周期的正常装载现象
能否再进一步说明一下,你的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;
没有使用移相模块
void InitEPwm1Example() { EPwm1Regs.TBPRD = 1000; // Set timer period EPwm1Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm1Regs.TBCTR = 0x0000; // Clear counter // // Setup TBCLK // EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; 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.LOADAMODE = CC_CTR_PRD; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Load registers every ZERO EPwm1Regs.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 actions EPwm1Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION; // Set PWM1A on Zero EPwm1Regs.AQCTLA.bit.CAU = AQ_NO_ACTION; EPwm1Regs.AQCTLA.bit.CBU = AQ_NO_ACTION; // Set PWM1B on Zero EPwm1Regs.AQCTLB.bit.CBU = AQ_NO_ACTION; // Set PWM1B on Zero EPwm1Regs.AQCTLB.bit.CAU = AQ_NO_ACTION; EPwm1Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION; // Set PWM1A on Zero EPwm1Regs.AQCTLB.bit.PRD = AQ_NO_ACTION; // Set PWM1B on Zero EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on Zero EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.PRD = AQ_CLEAR; // Set PWM1B on Zero EPwm1Regs.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 period EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm2Regs.TBCTR = 0x0000; // Clear counter // // Setup TBCLK // EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading 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.LOADAMODE = CC_CTR_PRD; EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Load registers every ZERO EPwm2Regs.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 actions EPwm2Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION; // Set PWM1A on Zero EPwm2Regs.AQCTLA.bit.CAU = AQ_NO_ACTION; EPwm2Regs.AQCTLA.bit.CBU = AQ_NO_ACTION; // Set PWM1B on Zero EPwm2Regs.AQCTLB.bit.CBU = AQ_NO_ACTION; // Set PWM1B on Zero EPwm2Regs.AQCTLB.bit.CAU = AQ_NO_ACTION; EPwm2Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION; // Set PWM1A on Zero EPwm2Regs.AQCTLB.bit.PRD = AQ_NO_ACTION; // Set PWM1B on Zero EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on Zero EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR; // Set PWM1B on Zero EPwm2Regs.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 period EPwm2Regs.GLDCTL.bit.OSHTMODE=1; EPwm2Regs.GLDCTL.bit.GLD=1; // active as GLDMODE bits EPwm2Regs.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 period EPwm4Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm4Regs.TBCTR = 0x0000; // Clear counter // // Setup TBCLK // EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD; EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Load registers every ZERO EPwm4Regs.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 actions EPwm4Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION; // Set PWM1A on Zero EPwm4Regs.AQCTLA.bit.CAU = AQ_NO_ACTION; EPwm4Regs.AQCTLA.bit.CBU = AQ_NO_ACTION; // Set PWM1B on Zero EPwm4Regs.AQCTLB.bit.CBU = AQ_NO_ACTION; // Set PWM1B on Zero EPwm4Regs.AQCTLB.bit.CAU = AQ_NO_ACTION; EPwm4Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION; // Set PWM1A on Zero EPwm4Regs.AQCTLB.bit.PRD = AQ_NO_ACTION; // Set PWM1B on Zero EPwm4Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on Zero EPwm4Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm4Regs.AQCTLB.bit.PRD = AQ_CLEAR; // Set PWM1B on Zero EPwm4Regs.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 period EPwm4Regs.GLDCTL.bit.OSHTMODE=1; EPwm4Regs.GLDCTL.bit.GLD=1; // active as GLDMODE bits EPwm4Regs.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 period EPwm6Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0 EPwm6Regs.TBCTR = 0x0000; // Clear counter // // Setup TBCLK // EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // Load registers every ZERO EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD; EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; // Load registers every ZERO EPwm6Regs.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 actions EPwm6Regs.AQCTLA.bit.ZRO = AQ_NO_ACTION; // Set PWM1A on Zero EPwm6Regs.AQCTLA.bit.CAU = AQ_NO_ACTION; EPwm6Regs.AQCTLA.bit.CBU = AQ_NO_ACTION; // Set PWM1B on Zero EPwm6Regs.AQCTLB.bit.CBU = AQ_NO_ACTION; // Set PWM1B on Zero EPwm6Regs.AQCTLB.bit.CAU = AQ_NO_ACTION; EPwm6Regs.AQCTLB.bit.ZRO = AQ_NO_ACTION; // Set PWM1A on Zero EPwm6Regs.AQCTLB.bit.PRD = AQ_NO_ACTION; // Set PWM1B on Zero EPwm6Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on Zero EPwm6Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm6Regs.AQCTLB.bit.PRD = AQ_CLEAR; // Set PWM1B on Zero EPwm6Regs.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 period EPwm6Regs.GLDCTL.bit.OSHTMODE=1; EPwm6Regs.GLDCTL.bit.GLD=1; // active as GLDMODE bits EPwm6Regs.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 }
EALLOW; EPwm2Regs.GLDCTL2.bit.OSHTLD=1; // EPwm4Regs.GLDCTL2.bit.OSHTLD=1; // EPwm6Regs.GLDCTL2.bit.OSHTLD=1; EDIS;
这是global load全局装载的代码,在所有受影响的EPWM寄存器赋值完的最后执行
1. EPWM1的时间基准功能其实有些多次一举。正如我之前所说,在初始化EPWM之前关闭EPWM外设时钟,初始化之后再使能,就能实现你想要的效果。
2. 就算EPWM2\4\6要按你设计的方式以EPWM1为基准,也应该使能移相:
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
spruhx5g_TMS320F2837xS Microcontrollers Technical Reference Manual (Rev. G) P1747