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.

[参考译文] CCS/TMS320F2.8379万D:ADC在更新EPwmReg1.CMPA后挂起

Guru**** 2032800 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/617816/ccs-tms320f28379d-adc-halts-after-updating-epwmregs1-cmpa

部件号:TMS320F2.8379万D

工具/软件:Code Composer Studio

尊敬的:

我已经为TMS320F2.8379万D编写了一个程序,它是一个基本控制环路应用程序,总共使用4个互补PWM信号EPwmRegs1...4,SO 8 PWM输出。 EPwmRegs5 PWM通道被配置并用于在切换周期的中间触发ADC。 该周期主要如下所示:

  1. ePwmRegs5.CMBB设置在切换周期的一半,并触发ADC
  2. 在ADC ISR例程中,对测量进行处理(偏移补偿和缩放),并调用CLA例程来计算新的占空比
  3. 同样在ADC ISR例程中,新的占空比值加载到EPwmRegs1...4.CMPA中

如果省略步骤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中设置的任何标志。


    此致,
    克里斯

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Kris,

    感谢你的帮助。

    到目前为止,我已经按照你的建议,用20行NOP测试了这一例行程序,但没有更新占空比。 一切都运行正常,整个周期需要1098个时钟周期,由于NOP,比以前稍多一些。 因此ISR仍处于触发状态。

    我不是两次调用setDutyCycle,它确实只是为了测试目的。

    此外,正如你所建议的,我核实了ETFLG登记册。 似乎EPwm5Regs.ETFLG寄存器的SOCA位已正确设置为触发ADC。 但是,不再设置ADCINT标志。 因此,我将进一步研究中断例程,因为DSP卡在该例程中。

    我将随时向您通报我的进展情况,但我们始终欢迎您提出更多建议。 谢谢!

    此致,
    Giel