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.

[参考译文] TMS320F28335:eCAP、ePWM 与 amp;pid 代码... 挑战性。 PWM 是主要问题所在。

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1258079/tms320f28335-ecap-epwm-pid-code-implementation-pwm-is-a-major-concern

器件型号:TMS320F28335

尊敬的 TI 社区成员:

之前、我在上一个线程中从事 ECAP 和 ePWM 模块的工作、然后成功实现了这两个 模块。 此任务从函数发生器获取输入、作为从 ECAP 函数获取具有频率和占空比的数字脉冲信号、然后通过 ePWM 函数复制或生成具有相同频率和占空比的相同脉冲。 代码运行得很好、我可以看到变量值  PWM_PERIOD 和 PWM_DUTY  以 TBPRD 为单位(     分别对于10kHz PWM_PERIOD =15000和 PWM_DUTY = 7500)...(先前的工作)。

当您遇到这种情况时、 我添加 PID 代码 例程  (常用代码) 第297-323行的代码和 pid 代码使用 while 循环 。 我初始化  while 循环 首先从线路294或线路300但然后我 放弃这个想法和使用在线路268因为一旦我 从函数发生器获得信号的频率/周期和占空比,它必须 工作在相同的信号,我 从函数发生器我可以调谐 此函数发生器 信号 、因此 while 环路必须相应地运行。

(也许你可以建议更好的位置这 while 循环或我的 PID 常用代码后看到我的结果图片)。  

注意:此处我不使用任何 DCL 库进行 PID 仿真。 对于一些背景信息、例如在极食、Matlab 或其他微控制器中、pid 例程代码通常用于 pid 仿真。 添加 pid 例程代码的原因是要根据如下条件更新 pid while 循环后的周期和占空比 新周期/新占空比。

常用 PID 代码:  

while (1)

 {

  E =(ref-a1);
  SE = se + e;
  DE = e-le;
  PID_OUT =(KP*e)+(KI*SE)+(KD*DE);// PID 方程
  LE = e;

 }

现在、我在这里添加结果、以澄清情况。

图片1:当从 Func 发生器应用10kHz、然后使用断点时、我按一次绿色按钮(调试):表达式窗口中的变量 PWM_PERIOD、PWM_DUTY 将提供大约正确的值14997和7495。 (TBPRD =15000 & TBPRD/2=7500)。

图1:

仍在使用绿色(调试)、 第328行的最后断点。 仍然没有问题、这些值正在自行更新。 然后、我开始使用 Assembly step into 函数、在断点之后从 CCS 工具栏中检查 EPwmRegs 的 TBPRD 和 CMPA/CMPB 值、该寄存器 EPwmRegs 的值也在自行更新。 到目前为止还没有问题。

见图2,图3。 您可以看到表达式窗口、它提供的值与可以完美地工作的值相同。

图2:

图3:

现在、它再次跳至 while 循环:请参阅 图4

图4:

此处问题从图5开始。 我的原始 PWM_Duty 会发生变化、这是我无法预期的。 因为我 没有 更改函数发生器信号的任何内容、所以该信号的值必须与 从图 1开始处看到的值 大致相同:PWM_PERIOD、PWM_DUTY 14997和7495。 然后、它开始在循环运行时更改表达式窗口中的每个变量。 所以我在这里怀疑 位置 共  while 循环 。 或使用我 常用的 PID 代码 位置。

图5

请根据相关建议

谢谢

敬礼

阿尔萨兰

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

    尊敬的 Arsalan:

    while 循环的放置似乎没有必要、因为我假定 eCAP 持续运行、何时触发 ISR? 您的中断中的 while (1)循环背后的原因是什么? 在 while 循环中也会清除中断标志。 中断将根据特定事件发生、因此似乎不需要 while (1)循环。 还要再次进行检查、看看您是在连续模式下运行还是在一次性模式下运行。

    此致!

    马瑞安

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

    您好、Ryan、

    感谢您的回复和建议、非常有帮助。

    首先、我可能会请您的帮助来解释该计划的流程、此外、我还将介绍我今天在实验室工作中获得的最新更新。

    实际上、我只是想 在 CCS 程序代码中通过 MATLAB 实现此 pid 仿真。 有关 MATLAB 仿真、请参阅下图。 该图形有两个图:一个是输入:errVec ( 我随机采用的值 )和其他为 pid_out ( 输出如下: )在 pid 后,循环结束。

    在 Matlab 代码中、errVec 是我认为  代码中的 a1、列于第316行 。 如您在 Matlab 程序中所见、我自己植入了 errVec 值、这是一个假设值、然后得到 pid_out 值 但在现实中、它将是我的 PWM_PERIOD 和 PWM_DUTY 直到(ECAP)从 Func Gen 获取的 。 如果您在 Matlab 程序中看到 pid_out、则循环结束时出现一次 pid_out。 但在我的 CCS 代码中、我使用 while 循环、因为我会始终连续捕获信号并生成 PWM 信号

    我知道我之前的工作还在 使用 ISR 实时捕获和生成 PWM 信号、但该代码中没有参考设置情况。 这就是我使用 pid 例程代码的原因。pid 例程代码使用引用、然后在循环结束后为 pidout 生成新值(如果是 CCS 代码:new Duty)、使用 pid 等式中的 Kp (propotional)、Ki (integration)和 Kd (derivative)值:

    PID_OUT =(KP*e);+(KI*se)+(KD*DE);// PID 方程

    因此、使用 while 循环是因为我可以设置参考并获取错误值、或者使用 pid 例程、而这在之前的工作中是没有这样做的。

    实验工作:

    今天、我再次检查了程序、然后移动了主函数中的 while 循环:

    在主函数的第120行已经有一个 while for CPU timer0、我在  Setup_ePWM1() func 之前的第85行注释掉了这个 while; 它以某种方式模拟了整个程序、包括具有 pid 例程代码的 Setup ePWM、Setup eCAP、CPU timer0和 ISR。

    因此、在这种变化之后、每当我按周期和占空比生成 Func 发生器信号、然后按 Debug (绿色)时、我的表达式窗口中的所有变量都会显示 "目标正在运行" 。 我在表达式窗口中看不到任何值。 这意味着(实时仿真无法计算这些值)。 因此、我按 SUSPEND (黄色)、然后它为我提供了相同的 TBRD (PWM_PERIOD)和 PWM_DUTY 值、这些值是我通过 Func 发生器生成的。 通过这种方式、我可以获取在 Suspend (黄色)操作期间在表达式窗口中更新的所有变量值。

    当我看到这件事时、我感到很高兴。 但是、当我开始改变 信号频率、比如20kHz、30kHz 时、会出现问题... 和占空比30%、40...60%…… 执行代码调用、然后 检查 示波器上的频率和占空比。 在几个设置后、信号停止捕捉。 它在示波器上显示平坦的信号(不再发生捕获)。

    这是 CPU 计时器的问题吗? 或者在第120行注释 while 循环、然后  在第85行创建 while 循环是个问题吗??? 如果您也可以解释程序和 func 的流程、以便我能够了解应该从何处启动 while 循环。

    工作的目的就像实时捕获信号的频率和  占空比、然后通过 pid 代码处理 dutyCycle、然后在 pid 公式后生成新占空比、最后必须生成具有新占空比的 PWM 信号。 同时完成所有任务。

    (请记住、我只在过程之后生成新的占空比、而不是新的周期/频率。 旧周期/频率我在代码中保持不变)  

    (我只关注 ePWM1、另一个 ePWM2、稍后我会看到)。

    请提出相应建议。

    谢谢

    此致

    阿尔萨兰

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这是 CPU 计时器的问题吗? 或者在第120行注释 while 循环、然后  在第85行创建 while 循环是个问题吗??? 如果您也可以解释程序和 func 的流程、以便我能够了解应该从何处启动 while 循环。

    在初始化周围的第85行创建 while 循环将导致意外行为。 在无限 while 循环之前、您的初始化代码只应被调用一次。

    行120之前的一切都用于初始化、只能调用一次。

    while 循环中的任何代码都将被反复调用、并导致出现问题。

    此致!

    马瑞安

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

    您好、Ryan、

    感谢您的答复。 感谢您的建议。 (抱歉、我将我的问题编辑为本答复中的更多说明)。  

    行120之前的一切都用于初始化、只能调用一次。

    while 循环中的任何代码都将被反复调用、并导致出现问题。

    这意味着、行120之后除了 CPU 计时器之外、不会在 main func 中留下任何内容、我无法将其放入 main func 中。 这个  基于 PID 的 while 循环。 对吧?

    我的想法是实施 基于 PID 的 while 循环 控制逐步 eCAP ->处理占空比直通(pid)->然后立即生成全部 ePWM、这在行80 (GPIO_select ()后无法从主函数执行。 现在、 我还可以使用基于 pid 的 while 循环的其他哪些可能性?  我还尝试过将其放置在 基于 PID 的 while 循环  在中断函数的第306或312行、但这不起作用、该函数连续运行、而且它不会从循环中产生。 然后、我尝试了第281行中断函数的开始、因为我认为它将涵盖所有方面(ecap、new_Duty、ePWM)、但它不在示波器上提供任何响应。  

    如果我可以设置一个条件 、在306,312或80或281行结束基于 pid 的 while 循环并有一定的延迟、或使其处于睡眠模式、或者在处理占空比后设置一些条件停止、然后发送其余更新的占空比、 将发送到 ePWM 端口...? 这可能会减少示波器上的结果崩溃、或者 如果反复调用也不会出错。  

    另一个问题:  

    当我开始在 CCS 工具中使用 assembly into 按钮(绿色箭头)时、看到分步行执行、然后它从第72行(int counter=0;)开始。 将执行每一行 、其中包括 对不同已初始化函数(如 setup_epwm1、setup_epwm2、setup_ecap 等)的跳 转或 func 调用、涉及到行104 (PieVectTable.ECAP1_INT=&eCAP1_ISR;)时、其中定义了中断[ eCAP1_ISR ]、然后逐行移动到同一主函数中的同一个函数。 直到线路112 (PieCtrlRegs.PIEIER4.bit.INTx1 = 1;)和线路115 ( EINT;)用于启用中断、然后它进入 CPU 定时器的 while 循环 、while (CpuTimer0.InterruptCount = 0);CpuTimer0.InterruptCount = 0;  

    在此 期间(CpuTimer0.InterruptCount =0);之后、汇编步骤进入(绿色箭头按钮)移动并保持在此 CPUtimer 中。 问题是自始至终、此汇编步骤 into (绿色箭头)函数不会检查、进入或检查 [interrupt void eCAP1_ISR (void)] func、也不会检查此 func 中的任何一个。 为什么??  

     

    请提出相应建议。

    谢谢  

    此致

    阿尔萨兰

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

    尊敬的 Arsalan:

    在此 期间(CpuTimer0.InterruptCount =0);之后、汇编步骤进入(绿色箭头按钮)移动并保持在此 CPUtimer 中。 问题是自始至终、此汇编步骤 into (绿色箭头)函数不会检查、进入或检查 [interrupt void eCAP1_ISR (void)] func、也不会检查此 func 中的任何一个。 为什么??  

    [/报价]

    您是否曾尝试在这些中断之一的开头放置一个断点? 您是否尝试过自行运行基本计时器示例?  

    我还有什么可能性可以使用 pid-based-while 循环?

    这不会进入主函数内的 while 环路吗? 在初始化外设之后、控制逻辑应该位于主 while 循环内部、并且任何需要处理的中断都可以将您的变量更新到 ePWM。  

    您是否看过 C20000数字控制库来了解一个基于 pid 的 while 环路示例?

    https://www.ti.com/tool/C2000-DIGITAL-CONTROL-LIBRARY

    此致!

    马瑞安

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

    您好、Ryan

    感谢您的答复。 总是乐于助人!

    您是否曾尝试在这些中断之一的开头放置一个断点? 您是否尝试过自行运行基本计时器示例?  

    如果我在中断函数中的开始位置设置一个断点、然后开始检查汇编指令 step into (绿色箭头)、这样就能正常工作。

    对于基本计时器示例、您是否可以为运行的基本计时器提供任何示例(示例示例)或代码以观察其工作情况?

    这不会进入主函数内的 while 环路吗? 在初始化外设之后、控制逻辑应该位于主 while 循环内部、并且任何需要处理的中断都可以将变量更新到 EPWM

    我只是从 interrupt func 中删除了基于 pid-while 的循环代码、然后从第115-144行移动到如下代码所示的 main 函数。 在我测试此代码时似乎可以正常工作。

     

    您是否看过 C20000数字控制库来了解一个基于 pid 的 while 环路示例?

    https://www.ti.com/tool/C2000-DIGITAL-CONTROL-LIBRARY

    是的、我之前介绍过、其中也有 DCL 指南。 但它使用了 pid 函数调用:->  

    //运行 PID 控制器
    UK = DCL_runPID_C4 (&pid1、rk、yk、lk);  

    我之前测试过 DCL 示例程序、该程序也在运行。 但在这里、我不希望在这里使用该 DCL 函数。 另外、如果我们查看示例 DCL 程序、 在这个函数 UK 中、该函数与机器语言文件(.asm)文件相关 、我没有深入研究该 asm 代码、但在这里、我在程序中使用了常用的 pid 例程、而循环代码是使用 C 语言。 因此我试图使用这个基于 pid 的 while 循环例程来实现我的 C 代码。  

    我认为、当循环在 main func 中工作时、它看起来像是基于 pid 的、并解决了我这里的问题。

    非常感谢

    此致

    阿尔萨兰