TMS320F28P650SK: CAN的配置

Part Number: TMS320F28P650SK
以下程序是为了实现can的接收中断,并在接收中断发送数据,如果使能内环测试模式(收与发的Message Identifier一样),是可以进入实现数据收发测试,但是如果设置为外部循环测试或者取消测试模式会出现errorFlag = 1; 这是什么原因,如何解决?
void Init_cana_tr(void)
{
   
    CAN_enableController(CANA_BASE);
    CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    //CAN_enableTestMode(CANA_BASE, CAN_TEST_LBACK);


    CAN_setupMessageObject(CANA_BASE, 1, 0x20, CAN_MSG_FRAME_STD,CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_NO_FLAGS,8);   //
    // Initialize the receive message object used for receiving CAN messages.
    // Message Object Parameters:
    //      Message Object ID Number: 3
    //      Message Identifier: 0x1
    //      Message Frame: Standard
    //      Message Type: Receive
    //      Message ID Mask: 0x0
    //      Message Object Flags: Receive Interrupt
    //      Message Data Length: 8 Bytes (Note that DLC field is a "don't care"
    //      for a Receive mailbox)
    CAN_setupMessageObject(CANA_BASE, 3, 0x20, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,8);
                                                                              //使能接收中断
   
   *(unsigned long *)ucRXMsgData = 0;

   CAN_startModule(CANA_BASE);

}

interrupt void eCANINTA_isr(void)
{

uint32_t status;

    //
    // Read the CAN interrupt status to find the cause of the interrupt
    //
    status = CAN_getInterruptCause(CANA_BASE);

    // If the cause is a controller status interrupt, then get the status
    //
    if(status == CAN_INT_INT0ID_STATUS)
    {                                                                       //默认语句
        status = CAN_getStatus(CANA_BASE);
        // Check to see if an error occurred.
        //
        if(((status  & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 7) &&
           ((status  & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 0))
        {
            // Set a flag to indicate some errors may have occurred.
            errorFlag = 1;
        }
    }
    //
    // Check if the cause is the transmit message object 1
    //
    else if(status == 3)
    {
        //
        // Getting to this point means that the TX interrupt occurred on
        // message object 1, and the message TX is complete.  Clear the
        // message object interrupt.
        //

        CAN_readMessage(CANA_BASE, 3, ucRXMsgData);
       
        CAN_ctr=(ucRXMsgData[0]&4)>>2;
        if(CAN_ctr == 1&&ucRXMsgData[7]==0xaa)
        {
            //EnSystem = ucRXMsgData[0]&1;
             EnDrive = (ucRXMsgData[0]&2)>>1;
            // T_ctr=(ucRXMsgData[0]&8)>>3;

            // //Int_tmp = ucRXMsgData[1];
            // Brake_pwm=ucRXMsgData[1]*20;
            // SpeedRef_krpm=(float)(ucRXMsgData[3]+ucRXMsgData[2]<<8)*0.1;
            // Speed_acc_krpmps=(float)(ucRXMsgData[5]+ucRXMsgData[4]<<8)*0.001;
            // T_shell_set=ucRXMsgData[6];
        }
       


        CAN_clearInterruptStatus(CANA_BASE, 3);   //ID=1


        CAN_sendMessage(CANA_BASE,1,8,ucTXMsgData);  

        // Int_tmp = T_mos * 10;                  // 转频
        // byte_tmp = Int_tmp & 0x00FF;
        // ucTXMsgData[1] = byte_tmp;    //
        // byte_tmp = (Int_tmp & 0xFF00) >> 8;
        // ucTXMsgData[0] = byte_tmp;    //
        // ucTXMsgData[4] += 0x01;
        // ucTXMsgData[5] += 0x01;
        // ucTXMsgData[6] += 0x01;
        // ucTXMsgData[7] += 0x01;

        //
        // Increment a counter to keep track of how many messages have been
        // sent.  In a real application this could be used to set flags to
        // indicate when a message is sent.
        //
        txMsgCount++;

        //
        // Since the message was sent, clear any error flags.
        //
        errorFlag = 0;
    }

    //
    // Check if the cause is the receive message object 2
    //
    // else if(status == 2)                    //不设置发送中断
    // {
    //     //
    //     // Get the received message
    //     //
    //     CAN_readMessage(CANA_BASE, 2, ucRXMsgData);

    //     //
    //     // Getting to this point means that the RX interrupt occurred on
    //     // message object 2, and the message RX is complete.  Clear the
    //     // message object interrupt.
    //     //
    //     CAN_clearInterruptStatus(CANA_BASE, 2);

    //     //
    //     // Increment a counter to keep track of how many messages have been
    //     // received. In a real application this could be used to set flags to
    //     // indicate when a message is received.
    //     //
    //     rxMsgCount++;

    //     //
    //     // Since the message was received, clear any error flags.
    //     //
    //     errorFlag = 0;
    // }

    //
    // If something unexpected caused the interrupt, this would handle it.
    //
    else
    {
        //
        // Spurious interrupt handling can go here.
        //
    }
    // Clear the global interrupt flag for the CAN interrupt line
    CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP9;
}
  • 内环测试 也只能是验证一下软件逻辑关系是否正确 如果你要用外部测试 需要把控制器挂在can总线上 或者你有can总线分析仪也可以 

    只有一个can节点没法用外部测试 是会报错的 这点TRM文档里有描述

  • 我用的是下图所示的测试模式,这个也不能进行测试,需要CAN控制器吗?

  • 您好,

    我需要更多信息才能提供正确的响应。

    内环测试模式是什么意思? 内部 TX 到 RX 环回模式?

    测试的最终目标是什么? 可测试性意味着什么?

    如果我目前的理解是正确的、客户需要将 CAN 收发器连接到 CAN_RX 和 CAN_TX 引脚、以进行外部模式测试。

    有关实现 CAN 网络物理层的更多信息、请参阅下面两个文档

    控制器局域网物理层要求- https://www.ti.com/lit/slla270

    调试控制器局域网(CAN)物理层的基础知识- https://www.ti.com/lit/slyt529

x 出现错误。请重试或与管理员联系。