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.

TMS570LS3137: CAN中断发送报文时,发生报文ID和数据,报文ID和上一个发送的报文数据发送到总线上

Part Number: TMS570LS3137

我建一个CAN的环形缓冲,每个周期将要发送的CAN报文写到环形缓冲区里,然后调用SendCanTxBufInt()触发中断发送,在报文发送完后触发中断,在中断canStatusChangeNotification()中发送下一个报文,发送邮箱只用一个。

static uint32_t TransmitCanFrame(canBASE_t *CanX, uint32_t nMessageBox, const CanTRMsg * const TxMsg)
{
    uint32_t success  = 0U;

    if(canIsTxMessagePending(CanX, nMessageBox) != 0U)    /* 邮箱忙状态 */
    {
        return 0U;
    }
    canUpdateID(CanX, nMessageBox, TxMsg->MsgId | (uint32_t)0x40000000U | (uint32_t)0x20000000U);
    success = canTransmit(CanX, nMessageBox, TxMsg->Data);
    return success;
}
/* 中断程序 */
void canStatusChangeNotification(canBASE_t *node, uint32 notification)
{
    uint32_t success = 0U;      /* 发送状态标志 */
    SetCan_MsgBuf *TxBuf = &g_Can1TxBuf;
    CanTRMsg      *TxMsg = NULL;

    if((uint8)notification & canLEVEL_TxOK)     /* 发送完成 */
    {
        if(TxBuf->Cnt != 0U)
        {
            TxMsg = &TxBuf->Buf[TxBuf->Head];
    
            success = TransmitCanFrame(node , canMESSAGE_BOX1, TxMsg);   /* 报文发送 */
            if(1U == success)
            {
                TxBuf->Head = (TxBuf->Head + 1U) % CAN_BUF_SIZE;  /* 写缓冲头 */
                TxBuf->Cnt--;
            }
        }
        else
        {
            canDisableStatusChangeNotification(node);
        }
    }
}

/* 中断触发发送 */
void SendCanTxBufInt(canBASE_t *CanX, uint32_t nMessageBox)
{
    uint32_t success = 0U;      /* 发送状态标志 */
    SetCan_MsgBuf *TxBuf = &g_Can1TxBuf;
    CanTRMsg      *TxMsg = NULL;

   
    if(TxBuf->Cnt != 0U)
    {
        TxMsg = &TxBuf->Buf[TxBuf->Head];
        if(TxMsg == NULL)
        {
            return;
        }
        canEnableStatusChangeNotification(CanX);                    /* 使能中断 */
        success = TransmitCanFrame(CanX , nMessageBox, TxMsg);      /* 报文发送 */
        if(1U == success)
        {
            TxBuf->Head = (TxBuf->Head + 1U) % CAN_BUF_SIZE;
            TxBuf->Cnt--;
        }
    }
}

现在情况是,我一个周期发送多个报文,假设顺序是报文1->报文2->报文3->报文4,发送有时总线上收到的报文数据是报文2的ID和报文1的数据,ID和数据发生错位。我在刷新ID时专门判断了邮箱是否为空,防止ID刷新数据刷新失败(我是中断触发,发送成功触发中断,邮箱理论上是空的),但是该现象偶尔还会出现,我这个用法伤和程序上有没有问题?官方有没有相关的例程或者源码可以参考的?我在论坛上看了其它相关的问题,例如https://e2echina.ti.com/support/microcontrollers/hercules/f/hercules-safety-microcontrollers-forum/194236/tms570-can-id/600776的TMS570 动态CAN发送 ID 和 数据 发生错位现象,他的用法上跟我有点区别,其内部有一个回复指向英文论坛的帖子,但是打开是该帖子不存在,目前我现在只能在协议上想办法。

期待你们的回复~~ ^__^