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
大家好、我有一个应用、在该应用中、我将正交编码器安装在电机上、我需要非常精确地在单转和多转中表示位置。 理想情况下、最好将 eQEP 模块配置为以两种方式表示位置。 反过来、QPOSCNT 将由索引事件或当 QPOSCNT 达到编码器的最大节拍数时复位。 反过来、QPOSCNT 会在多个编码器旋转过程中继续累积位置。
我看不到在硬件中支持此功能的方法。 因此、我的选项似乎是1)将正交信号连接到两个不同的 eQEP 模块、并让一个处理单圈、另一个处理多圈。 这不适用于我当前的应用、因为硬件不能满足这一要求。
我当前使用的方法的第二个选项是在软件中查找上溢或下溢事件、并手动跟踪发生这种情况时添加或减去 MAX_ENCODER_TICK 的情况。 这可以正常工作、但有时 PCU/PCO (下溢/上溢)标志与 QPOSCNT 寄存器不同步。 我的意思是、我将在前台检测到上溢或下溢事件、但在 QPOSCNT 中看不到相应的跳转、反之亦然。 当我检查前台的过流/下溢标志时、我已经尝试在关键部分禁用 QEINT 寄存器中的 PCO / PCU 中断、在关键部分我读取了标志值和 QPOSCNT 值、但这似乎没有帮助。
是否有办法保证 PCU/PCO 标志与 QPOSCNT 寄存器同步、以便在其它更新之前无法读取其中一个标志?
您好!
处理单转和多转位置感应的第二种方法对我来说很好。 虽然您已经指出的与位置计数器下溢/溢出事件相关的同步问题并不十分清楚。 一旦下溢/上溢发生、就会产生一个中断事件、并且位置计数器将被复位并重新开始计数。 那么、这到底会如何影响您的计算呢? 此外、我认为、如果您可以共享前台 ISR 的代码片段、那将会有所帮助。
如果我的回复回答了您的问题、请点击位于我帖子底部的"我的问题已解决"按钮。
此致
Himanshu
您好、Himanshu、我已经为我的"前景 ISR"编写了一些代码、虽然它尚未经过彻底测试、但迄今为止似乎仍然有效(在我原始帖子之后发现了这一点)。 此代码以20kHz 的频率运行、因此在执行此代码之间通常只会发生 QPOSCNT 中的微小(<10)变化。
此代码比在 QPOSCNT 换行发生的同时发生 PTO/PTU 事件所需的代码复杂得多。 但是、从我在这里进行的检查中可以看出、在某些情况下、PTO/PTU 被触发、但 QPOSCNT 尚未缠绕、或 QPOSCNT 在 PTO/PTU 被触发之前发生缠绕。
其中包括:
//尝试防止上溢/下溢标志在本节期间发生变化,不确定这是否起作用 fclVars[0].ptrQEP->QEINT.bit.PCO = 0; fclVars[0].ptrQEP->QEINT.bit.PCU = 0; //保存以前的状态 numwrap_prev = fclVars[0].QEP.numWraps; poscnt_prev = poscnt; fclVars[0].QEP.cnts_unwrapped_prev = fclVars[0].QEP.cnts_unwrapped; //更新位置 poscnt = fclVars[0].ptrQEP->QPOSCNT; if (poscnt - poscnt_prev <-100 && fclVars[0].ptrQEP->Qlp.bit.PCO){//检测到溢出事件,100是一个小于编码器节拍(4000)的"大"数字 fclVars[0].ptrQEP->QCLR.bit.PCO = 1;//清除 PCO 标志 fclVars[0].QEP.numWraps++; fclVars[0].QEP.cnts_unwrap= fclVars[0].QEP.numWraps * 4000 + poscnt; waitingForPCO = 0; } 否则、如果(poscnt - poscnt_prev > 100 && fclVars[0].ptrQEP->Ql.bit.PCU){//检测到下溢事件 fclVars[0].ptrQEP->QCLR.bit.PCU = 1;//清除 PCU 标志 fclVars[0].QEP.numWraps--; fclVars[0].QEP.cnts_unwrap= fclVars[0].QEP.numWraps * 4000 + poscnt; 等待 ForPCU = 0; } 否则、如果((poscnt - poscnt_prev > 100 &&!fclVars[0].ptrQEP->Qql.bit.PCU)|| waitingForPCU){/qposcnt 欠流、但无 PCU 事件 fclVars[0].QEP.cnts_unwrap= fclVars[0].QEP.numWraps * 4000 + poscnt - 4000; 等待 ForPCU++;//poscnt 已缠绕,但 PCU 未反映此 情况} 否则、如果((poscnt - poscnt_prev <-100 &&!fclVars[0].ptrQEP->QFLG.bit.PCO)|| waitingForPCO){/qposcnt 溢出但没有 PCO 事件 fclVars[0].QEP.cnts_unwrap= fclVars[0].QEP.numWraps * 4000 + poscnt + 4000; waitingForPCO ++;//poscnt 已缠绕,但 PCO 未反映此 情况} 否则、如果(abs (poscnt - poscnt_prev)> 100){ UNK_ERR++;//未知错误,至今尚未发生 } 否则{ fclVars[0].QEP.cnts_unwrap= fclVars[0].QEP.numWraps * 4000 + poscnt; } //重新启用过流/欠流标志 fclVars[0].ptrQEP->QEINT.bit.PCO = 1; fclVars[0].ptrQEP->QEINT.bit.PCU = 1;
您好!
我查看了上述代码片段,并有以下问题:
if
(poscnt - poscnt_prev < -100) -> definitely overflow or if
(poscnt - poscnt_prev > 100) -> definitely underflow.
最后、在 TRM 中的"位置计数器重置为最大位置"部分中提供的下图中非常清晰地说明了上溢/下溢行为、这将有助于您分析和调试问题。
如果我的回复回答了您的问题、请点击位于我帖子底部的"我的问题已解决"按钮。
此致
Himanshu
[引用用户="Himanshu Chaudhary60"]
如果预期的计数器值变化已经被称为~ 10、那么对于测试用例、比较当前计数器值和以前的计数器值>/< 100/- 100、为什么需要检查 PCC/PCU? if
(poscnt - poscnt_prev < -100) -> definitely overflow or
if
(poscnt - poscnt_prev > 100) -> definitely underflow.
[/报价]
是的、我希望这也能起作用、但我不喜欢这种方法依赖于"魔数"、并且不能保证在所有情况下都能正常工作。
[引用用户="Himanshu Chaudhary60"]
即使我们决定使用 PCO / PCU 标志、为什么在读取位置计数器值之前禁用它们? 如果上溢/下溢即将设置确切的时间读数、那么读取该值后禁用该读数是否更好?
[/报价]
我在这里的想法是、如果在读取其中一个值后 PCC/PCU 或 QPOSCNT 发生变化、但不读取另一个值、则可能会引入错误。 但我认为您认为 PCO/PCU 可能不会改变、但 QPOSCNT 仍可能改变。 我还注意到、如果我使用 QPOSLAT、我看到的问题会变得更糟、因为它以10kHz 的频率锁存。
[引用用户="Himanshu Chaudhary60"]
在上述用例中是否也使用索引信号? 如果是、请注意 有一个与 eQEP 相关的勘误项:位置计数器在索引期间错误地重置方向更改、因此请确保这是您用例中的比例帐户。 有关这方面的更多信息和权变措施、请参阅 TI 产品页面上提供的 F2837x 勘误表文档。
[/报价]
该索引用于将 QPOSCNT 设置为 QPOSINIT。 我看到的错误是电机在一个方向上高速旋转。 我想、如果编码器信号上有任何噪声、则可能会发生错误检测到的方向变化。 我将查看此勘误表。
[引用用户="Himanshu Chaudhary60"]
最后、在 TRM 中的"位置计数器重置为最大位置"部分中提供的下图中非常清晰地说明了上溢/下溢行为、这将有助于您分析和调试问题。
[/报价]
是的、我已经看过这张图、并了解它的工作原理。 事实上、我正在尝试在软件中"解封"QPOSCNT 值、但这是一个挑战、在这种情况下、时序和同步比在硬件中更难保证。
好的、如果您能够根据上述讨论的信息和资源调试和解决问题、请随时向我们发送。
如果我的回复回答了您的问题、请点击位于我帖子底部的"我的问题已解决"按钮。
此致
Himanshu