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.
尊敬的 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 的、并解决了我这里的问题。
非常感谢
此致
阿尔萨兰