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/TMS320F28375D:QEP QPOSCNT 累积问题

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/957302/ccs-tms320f28375d-qep-qposcnt-accumulation-issue

器件型号:TMS320F28375D

工具/软件: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; 

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

    您好!

    我查看了上述代码片段,并有以下问题:

    • 如果预期的计数器值变化已经被称为~ 10、那么对于测试用例、比较当前计数器值和以前的计数器值>/< 100/- 100、为什么需要检查 PCC/PCU?   if(poscnt - poscnt_prev < -100) -> definitely overflow or if(poscnt - poscnt_prev > 100) -> definitely underflow.

    • 即使我们决定使用 PCO / PCU 标志、为什么在读取位置计数器值之前禁用它们? 如果上溢/下溢即将设置确切的时间读数、那么读取该值后禁用该读数是否更好?

    • 在上述用例中是否也使用索引信号? 如果是、请注意 有一个与 eQEP 相关的勘误项:位置计数器在索引期间错误地重置方向更改、因此请确保这是您用例中的比例帐户。 有关这方面的更多信息和权变措施、请参阅 TI 产品页面上提供的 F2837x 勘误表文档。

    最后、在 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