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.
工具/软件:Code Composer Studio
尊敬的:
我已经为TMS320F2.8379万D编写了一个程序,它是一个基本控制环路应用程序,总共使用4个互补PWM信号EPwmRegs1...4,SO 8 PWM输出。 EPwmRegs5 PWM通道被配置并用于在切换周期的中间触发ADC。 该周期主要如下所示:
如果省略步骤3,则整个序列正常运行,并且我验证了从测量到控制输出的整个周期的持续时间。 根据测量值确定新的控制设置平均需要1027个周期(5 us)。 如果我要将新的占空比命令发送到EPwmReg1.CMPA寄存器,则例程停止,并且不再调用ADC ISR。 但是,处理器的主环路继续运行,这表示处理器仍在运行。
请您就该错误的根本原因以及如何解决该问题提供建议吗? 我在下面列出了一些代码摘录,以供澄清。
感谢你的帮助。
Giel
PWM的设置
(* ePWM[j]).TBCTL.bit.PRDLD = TB_shadow;//设置阴影负载(在下一个切换周期启用PWM值) (*ePWM[j])。TBPRD =周期; // PWM频率=1/(2*TBPRD) //(* ePWM[j]).cmpa.bit.cmpa =周期/ 2;//初始设置占空比50 % (* ePWM[j]).CMPA.bit.CMPA = 0; //初始设置占空比0 % (*ePWM[j]).CMPA.bit.CMPAHR =(1<8);//初始化HRPWM扩展(<< 8表示向左操作数移动8位) (* ePWM[j]).CMPB.bit.CMPB =周期/ 2;//初始设置占空比50 % //(* ePWM[j]).CMPB.all |= 1; (* ePWM[j]).TBPHS.ALL = 0; (* ePWM[j]).TBCTR = 0; (* ePWM[j]).TBCTL.bit.PHSEN = 1; (* ePWM[j]).TBCTL.bit.CTRMODE = TB_COUNT_UP; //选择UP计数模式(上升) //计数模式 (* ePWM[j]).TBCTL.bit.SYNCOSEL = TB_SYNC_IN; //同步ePWM时钟 (* ePWM[j]).TBCTL.bit.HSPCLKDIV = TB_DIV1; (* ePWM[j]).TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT (* ePWM[j]).TBCTL.bit.FREE_SOFT = 11; (* ePWM[j]).CMPCTL.bit.LOADAMODE = CC_CTR _PRD;//在CTR = 0上加载CMPA (* ePWM[j]).CMPCTL.bit.LOADBMODE = CC_CTR_PRD; (* ePWM[j]).CMPCTL.bit.SHDWAMODE = CC_SHAMODE; //阴影寄存器存储PWM设置,直到下一个PWM周期有效应用它们 (* ePWM[j]).CMPCTL.bit.SHDWBMODE = CC_SHADOW; (* ePWM[j]).AQCTLA.bit.ZRO = AQ_SET; // PWM切换高/低 (* ePWM[j]).AQCTLA.bit.CAU = AQ_CLEAR; (* ePWM[j]).AQCTLB.bit.ZRO = AQ_SET; // PWM切换高/低(注:位DBCTL.bit.POLSEL进一步向下指定PWM通道信号的兼容性) (* ePWM[j]).AQCTLB.bit.CAU = AQ_CLEAR;
设置PWM以触发ADC
EPwm5Regs.ETSEL.bit.SOCASEL = ET_CTRU_CMPB; //当计数器等于CMPB时触发SOC,它设置在交换周期的一半
EPwm5Regs.ETPS.bit.SOCAPRD = ET_1ST; //在每个事件上生成脉冲
EPwm5Regs.ETSEL.bit.SOCAEN = 1; //在组上启用SOC
每个ADC SOC通道都由EPwmRegs5的SOCA触发
ADcaRegs.ADCSOC1CTL.bit.TRIGSEL = 13; // ePWM5 SOCA上的触发器
ADC ISR例程:
//过程测量
CLA_PROCESS_Measurements();
//检查保护限制
保护();
//状态机
State_machine();
//管制法
RunControlLaw();
//设置占空比
//setDutyCycle (5005.005005亿);
//setDutyCycle (res3[2],res3[3],res3[4],res3[5]);
cycle_duration = CpuTimer0Regs.PRD.bit.LSW - CpuTimer0Regs.TIM.bit.LSW;
//确认中断
ADcaRegs.ADCINTFLGCLL.bit.ADCINT1 = 1;//清除INT1标志
PieCtrlRegs.PIEACG.ALL = PIEACK_GROUP1;
res3[2]...[5]是由CLA计算的4个占空比。
setDutyCycle (setDutyCycle):
//
// setDutyCycle -设置转换器的占空比
//
void setDutyCycle (UINT16 pwm1,UINT16 pwm2,UINT16 pwm3,UINT16 pwm4)
{
EPwm1Regs.CMPA.bit.CMPA = pwm1;
EPwm2Regs.CMPA.bit.CMPA = pwm2;
EPwm3Regs.CMPA.bit.CMPA = pwm3;
EPwm4Regs.CMPA.bit.CMPA = pwm4;
}
您好,Giel,
由于setDutyCycle函数与触发ADC的EPWM5无关,我倾向于这是一个计时问题。如果您对setDutyCycle进行注释,并通过输入ASM(" NOP")将其替换为一系列NOP(10-20),ISR路由是否会继续被触发?
您是否实际上在代码中调用了setDutyCycle两次,或者您只是使用此行上的已知值进行测试(setDutyCycle (5005.005005亿);)? 当它失败时,您是否可以检查各种中断标志的状态? ePWM中的ETFLG,应在ADC,PIEIFR,IFR中设置的任何标志。
此致,
克里斯