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.

[参考译文] TMS320F2808:CAN 总线超时不一致

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1042842/tms320f2808-can-bus-timeout-inconsistency

器件型号:TMS320F2808

当两个 CAN 器件的波特率相同时、我有一个电路是很好的。 我现在已经将终端设备设置为在启动时具有不同的波特率、以便有目的地导致 CAN TX 消息超时。 我觉得在我的"设置"超时中缺少一些东西、因为代码只在其他时间运行。

我的意思是、当 F2808为20Kbps 且终端器件为1Mbps 时、F2808第一次可以发送超时、然后移动到一个函数、将波特率更新为1Mbps、然后按照预期处理其余的 CAN 消息。 然后我停止执行、然后重新启动相同的代码、F2808以20Kbps 开始、CAN 消息超时、切换到1Mbps、但下一条消息失败、但我无法跟踪原因。 然后、我重新启动代码、执行相同的波特率过程、但这次它按预期工作。 每次其他 CPU 复位都按预期工作、但每次其他复位都失败。  

当发出下一个 CPU 复位时、故障状态期间的某些标志似乎被复位、但我似乎找不到它。

哪些关键标志可确保在 CAN TX 超时期间清除、如何将其复位?

或者、在尝试更改波特率(或在出现 A 时发送另一条消息)之前、我应该中止 Tx 消息吗?

PMDresult CAN_SendCmdMsg(struct CAN_CONFIG* cancfg, Uint16 bytecount, Uint16* bytes)
{
    PMDresult result = PMD_NOERROR;
    cancfg->TX_MBOX->MSGCTRL.bit.DLC = bytecount;
    // add bytes to mailbox
    StuffMailbox(cancfg, bytecount, &bytes[0]);

    /* Clear the "Time Stamp Counter"  */
    EALLOW;
    ECanaRegs.CANTSC = 0;
    EDIS;

    ECanRegsShadow.CANTRS.all = 0;
    ECanRegsShadow.CANTRS.all = cancfg->TX_BIT;     // Set TRS for mailbox under test
    ECanaRegs.CANTRS.all = ECanRegsShadow.CANTRS.all;
    //
    // Wait for TAn bits to be set
    // TODO Set timeouts on all do..while
    //
    ECanRegsShadow.CANTA.all = ECanaRegs.CANTA.all;
    do
    {
        ECanRegsShadow.CANTOS.all = ECanaRegs.CANTOS.all;
        ECanRegsShadow.CANTA.all = ECanaRegs.CANTA.all;
    } while((ECanRegsShadow.CANTA.all & cancfg->TX_BIT) == 0 && // Wait for TAx = 1 (Successful CAN transmit)
            (ECanRegsShadow.CANTOS.all & cancfg->TX_BIT) == 0); // TOS = 1 when timeout occurred
    /* Service a timeout? */
    if((ECanRegsShadow.CANTOS.all & cancfg->TX_BIT) == cancfg->TX_BIT)
    {
        // timeout occurred so clear the bit and move on
        ECanRegsShadow.CANTOC.all = ECanaRegs.CANTOC.all;
        ECanRegsShadow.CANTOC.all = cancfg->TX_BIT;
        ECanaRegs.CANTOC.all = ECanRegsShadow.CANTOC.all;
        // CANTOC should be clear now
        result = PMD_ERR_Timeout;
    }

    ECanRegsShadow.CANTA.all = 0;
    ECanRegsShadow.CANTA.all = cancfg->TX_BIT;         // Clear tx bit
    ECanaRegs.CANTA.all = ECanRegsShadow.CANTA.all;

    return result;
}

    /*
    * This bit globally enables all interrupts for the ECAN0INT line if the corresponding masks are set.
    */
    ECanRegsShadow.CANGIM.all = ECanRegsShadow.CANGIM.all;
    ECanRegsShadow.CANGIM.bit.I0EN = 1;   // Enable eCAN0INT
    ECanRegsShadow.CANGIM.bit.I1EN = 0;   // Disable eCAN1INT
    ECanRegsShadow.CANGIM.bit.MTOM = 1;   // Enable mailbox timeouts
    ecanregs->CANGIM.all = ECanRegsShadow.CANGIM.all;

    /*
     * Setup transmit and receive timeouts
     * Limit-value of the time-stamp counter (TSC) 100 clocks / uSec
     *    TSC is incremented by bit clock so it is independent of bit per second
     */
    ECanaMOTORegs.MOTO[INIT_TX_CANMBOX] = 0x400;
    ECanaMOTORegs.MOTO[INIT_RX_CANMBOX] = 0x400;
    ECanaMOTORegs.MOTO[AZ_TX_CANMBOX]   = 0x400;
    ECanaMOTORegs.MOTO[AZ_RX_CANMBOX]   = 0x400;
    /* Enable time-out function for the mailboxes */
    ECanaRegs.CANTOC.all = MAILBOX0BIT | MAILBOX5BIT | MAILBOX16BIT | MAILBOX21BIT;
    /* Clear the "Time Stamp Counter"  */
    ECanaRegs.CANTSC = 0;

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

    不确定这是否有用、但我在 GetID()的第一条消息中看到运行正常的下电上电、F2808在请求之后生成一个 ACK、但在下电上电失败时、没有 ACK、但消息帧是相同的。 不确定为什么 F2808不发送 ACK。 有什么想法吗? (连接的器件将在收到的每条消息后始终输出2个字节作为状态字节。)

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

    Jeffrey、

                   不匹配的位速率应会使发送节点迅速脱离总线状态。 你明白了吗? 当节点进入 BO 时、应设置 CCR 位。 如果您看到这种情况发生、则可以使用它来代替超时条件。 我对您尝试做什么有点不清楚。  

    在您的第二篇帖子中、您讨论的是 ACK、但来自谁的 ACK? 如果2808正在发送、则另一个节点将生成 ACK。 您认为 ACK 可能是 ACK 定界符、而不是 ACK 本身。 请记住、ACK 字段由两位组成。 发送器输出1、该值被输出0的接收器覆盖。 后跟一个0、即 ACK 定界符。  

    请阅读 www.ti.com/lit/spra876的第3.1和3.2节  以及 www.ti.com/lit/spra890的第2.1节

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

    我将稍微介绍一下"巴士关闭"-谢谢

    更新了- CANES 寄存器中的唯一位是 ACKE 和 SMA (我希望基于断点实现哪一个?)

    至于第二部分、我怀疑缺少 ACK 来自 F2808。 F2808查询(TX 0x605) 58113的 ID、然后58113应答(TX 0x585)。  第一条消息是 F2808 TX、下一条消息是来自58113的响应、因此它是复用的、F2808是复用的。 这就是我怀疑 F2808没有提供 ACK 的原因。

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

    当比特率相同时、每个节点都正确确认来自另一个节点的传输、因此您的设置中不存在硬件问题。  

    当比特率不匹配时、通信不会很远、因为接收器无法解释总线上的通信、并会破坏带有错误帧的持续传输。 传输甚至不会达到 ACK 阶段。  

    如果、在正常通信设置(匹配比特率)中、如果发送器没有接收到 ACK、则 ACKE 位将被置位。 在误匹配的位速率设置中、应以 CANES 为单位设置其他一些错误位。  

    您对 SMA 位的理解是正确的。

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

    请注意、在生成图像时、比特率是相同的。 这是在经历 F2808 TX 超时之后。

    您是否建议在位定时匹配之前不使用超时-而是使用超时?

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

    考虑到您的网络在正常情况下(即比特率相同时)工作正常、接收节点必须提供 ACK、除非处于脱离总线状态。 我不知道您如何处理从脱离总线状态恢复的问题。 它可以是自动(ABO=1)、也可以通过清除 CCR (ABO=0)手动完成。

    [引用 userid="352848" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1042842/tms320f2808-can-bus-timeout-inconsistency/3856942 #3856942"]是否建议在位时序匹配之前不使用超时-请改用超时?

    很抱歉,我不理解这个问题。 这听起来是自相矛盾的。

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

    我想问、您是否建议在两个器件都设置为相同的波特率之前关闭 CAN TX/Rx 超时功能?

    此外、如果出现超时、我希望了解如何恢复、以便 CAN 总线在发生故障时仍能保持活动状态。

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

    Jeffrey、

      也许通过电话进行讨论更节省时间。 将私下接触。

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

    这似乎与超时寄存器直接相关。 最初我在 CAN_Init()中设置了所有超时寄存器。 为了克服 TI 缺少 ACK 的问题、我将以下代码移至测试 CANRMP 接收超时之前以及设置 CANTRS 位进行发送超时之前:

        /* Enable and clear the "Time Stamp Counter"  */
        EALLOW;
        ECanRegsShadow.CANTOC.all = ECanaRegs.CANTOC.all;
        ECanRegsShadow.CANTOC.all |= (Uint32)(1 << mbox);
        ECanaRegs.CANTOC.all = ECanRegsShadow.CANTOC.all; // Set the time out enable
        ECanaRegs.CANTSC = 0; // Reset the time out counter
        ECanaRegs.CANGIF0.all  = 0xFFFFFFFF; /* Clear all interrupt flag bits */
        EDIS;

    MTOM 和 MOTO 寄存器仍在 CAN_Init()中声明。

    然后、在为接收超时设置 CANRMP 值之后、立即在发送超时设置 CANTA 之后、我立即向添加了以下代码:

        /* Disable and clear the "Time Stamp Counter"  */
        EALLOW;
        ECanRegsShadow.CANTOC.all = ECanaRegs.CANTOC.all;
        ECanRegsShadow.CANTOC.all &= ~(Uint32)(1 << mbox); // Disable specific time out
        ECanaRegs.CANTOC.all = ECanRegsShadow.CANTOC.all;
        ECanaRegs.CANTSC = 0; // Reset the time out counter
        EDIS;

    文档中似乎缺少从 CAN 超时恢复的能力、我也没有发现支持任何其他全局中断恢复的能力、即在全局问题发生后使 CAN 总线保持活动状态的能力。 如果能在这方面提供任何帮助,将不胜感激。

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

    Jeffrey、

       我刚刚编写了一个测试案例、并验证了比特率开关本身不是问题。 我以1Mbps 的速率将帧从 TI MCU 传输到总线分析仪、并正确接收到该数据。 然后、我将 MCU (和总线分析器)重新配置为50kbps、并让总线分析器传输一个@ 50kbps 的帧、该帧被 MCU 正确接收。  

    我将从今天晚上开始旅行。 将在星期一之前返回您的上一个帖子。

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

    我同意比特率的变化不是问题、但感谢您的确认。 :-)很高兴得到第二个意见!

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

    让我看一下您的代码片段、然后返回给您。 可能是星期一或星期二。 感谢您的耐心等待。