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/TMS320F28377D:CAN 通信

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/900239/ccs-tms320f28377d-can-communication

器件型号:TMS320F28377D
主题中讨论的其他器件: C2000WARE

工具/软件:Code Composer Studio

。、我最近在调试 CAN 通信时遇到了一些问题

首先、我使用 TMS320F28377D 代码示例/所有 CPU1示例/ CAN_EXTERNAL_Transmit 来调试 CAN 并定义 TX_MSG_OBJ_ID 2;RX_MSG_OBJ_ID 1。我可以接收消息并重新传输消息、但遇到一些错误。 如图1-3所示、

状态= CANIntStatus (CANA_base、CAN_INT_STS_CAUST);àstatus = 0x00008000

状态= CANStatusGet (CANA_base、CAN_STS_CONTROL);à 状态= 0x00000008

我如何处理这些道具?为什么?

其次、我可以接收特定 ID (0x00005555)的消息。 但是、如果我想首先接收所有消息、然后判断是否使用了 ID。 如何配置 sRXCANMessage 结构?

sRXCANMessage.ui32MsgID = 0x00005555;

sRXCANMessage.ui32MsgIDMask = 0;

sRXCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE;

  sRXCANMessage.ui32MsgLen = MSG_DATA_LENGTH;     

  sRXCANMessage.pucMsgData = rxMsgData;

  CANMessageSet (CANA_base、RX_MSG_obj_ID、sRXCANMessage、

                  MSG_OBJ_TYPE_RX);

非常感谢!

此致。

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

    您好!

    我看不到您所参考的图1-3、但0x8000的 CAN_INIT_STS_CAUSTER 指示 CAN_ES (CAN 状态寄存器)中的 LEC (最后一个错误代码)不是0x7。  遇到问题时、能否显示 CAN_ES 寄存器的内容?  这将更好地指示您遇到的问题。  不确定为什么没有从 ID 0x00005555以外的 ID 收到消息。  消息 ID 掩码已设置为0、因此应接收所有消息 ID。  让我们首先看看 CAN_ES、可能存在一个阻止 CAN 接收消息的潜在错误。

    此致、

    Joseph

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

    您好、Joseph

    当我从 ID 0x00005555接收到消息并重新发送消息时、CAN_ES 寄存器 TxOK = 1、如图1所示、但我仍然收到错误。

    状态= CANIntStatus (CANA_base、CAN_INT_STS_Cause);--- > STATUS = 0x00008000

    状态= CANStatusGet (CANA_base、CAN_STS_CONTROL);--- > STATUS = 0x00000008

    如图2所示、CAN_ES 寄存器 LEC = 0x7。   如何解决此问题?

    另一个问题、当我配置 sRXCANMessage.ui32MsgID = 0x0000555;sRXCANMessage.ui32MsgIDMask = 0时;我 可以从接收到中断  

    与0x00006666和 CAN_ES 寄存器类似的其他 ID 指示 RxOK = 1、如图3所示。 但 我无法从 ID = 0x00006666接收任何信息,因为状态= CANIntStatus (CANA_base、CAN_INT_STS_CAUST);--- >status = 0x00008000 如 图4所示,我找不到解决这个问题的方法,您能帮我吗?

    谢谢、致以诚挚的问候。

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

    黎高、

    看起来有一些挂起的中断会导致您获得这些状态。  您还能检查 CAN_IPEN_X 和 CAN_IPEN_21的值吗?  抱歉、您代码中的这些函数调用已被弃用、这会使调试时间更长、因为我只需返回旧示例了解这些函数即可。  如果您有机会迁移到最新的 C2000Ware CAN 功能、那将会很好。

    谢谢、此致、

    Joseph

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

    您好、Joseph、

    我听从您的建议、迁移到最新的 C2000Ware CAN 功能、但仍然存在相同的问题。 当我发送 ID=0x95555555消息时、我可以接收它并发生错误。 如果我将 ID 更改为0x95555556、ICA 将不接收消息。 图1-4所示为 ID=0x95555555相关寄存器、图5-8所示为 ID=0x95555556相关寄存器。 我按如下方式迁移 CAN_ex3_external_transmit。 可以帮助我检查问题吗? 非常感谢!

    //
    //包含的文件
    //
    #include "driverlib.h"
    #include "device.h"
    #include "stdlib.h"
    #include "string.h"
    #include "math.h"
    //
    定义
    //
    #define TXCOUNT 100000
    #define MSG_DATA_LENGTH 8
    #define TX_OBJ_MSG_ID 2
    #define RX_MSG_OBJ_ID 1
    
    //
    Globals
    //
    volatile unsigned long i;
    volatile uint32_t txMsgCount = 0;
    volatile uint32_t rxMsgCount = 0;
    volatile uint32_t errorFlag = 0;
    uint16_t MstxgData[8];
    uint16_t rxMsgData[8];
    
    //
    
    
    函数 rxaisr;//函数 void;//函数 rxaisr // CAN-A 的接收中断
    // CAN-A 无发送中断
    //_interrupt void canbISR (void); // CAN-B 的接收中断
    // CAN-A 无发送中断
    //
    // Main
    //
    void main (void)
    {
    //
    //初始化设备时钟和外设
    //
    device_init();
    
    //
    //初始化 GPIO 并为 CANTX/CANRX 配置 GPIO 引脚
    //在模块 A 和 B 上。device.h 文件可能需要修改为
    //在电路板中反映所选的 GPIO 引脚。
    //
    DEVICE_initGPIO();
    GPIO_setPinConfig (DEVICE_GPIO_CFG_CANRXA);
    GPIO_setPinConfig (DEVICE_GPIO_CFG_CANTXA);
    //GPIO_setPinConfig (DEVICE_GPIO_CFG_CANRXB);
    //GPIO_setPinConfig (DEVICE_GPIO_CFG_CANTXB);
    
    //
    //初始化 CAN 控制器
    //
    CAN_initModule (CANA_base);
    //CAN_initModule (CANB_BASE);
    
    //
    //为每个模块将 CAN 总线位速率设置为500kHz
    //有关如何设置的信息,请参阅驱动程序库用户指南
    //更严格的计时控制。 此外、请参阅器件数据表
    //了解有关 CAN 模块计时的更多信息。
    //
    //CAN_setBitRate (CANA_base、DEVICE_SYSCLK_FREQ、250000、20);
    CAN_setBitRate (CANA_base、DEVICE_SYSCLK_FREQ、50000、20);
    //CAN_setBitRate (CANB_BASE、DEVICE_SYSCLK_FREQ、50000、20);
    
    //
    //在 CAN B 外设上启用中断。
    //启用 Int.line0、错误和状态更改中断
    //
    CAN_enableInterrupt (CANA_base、CAN_INT_IE0 | CAN_INT_ERROR |
    CAN_INT_STATUS);
    // CAN_enableInterrupt (CANB_BASE、CAN_INT_IE0 | CAN_INT_ERROR |
    // CAN_INT_STATUS);
    
    //
    //初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
    //
    interrupt_initModule();
    
    //
    //使用指向 shell 中断的指针初始化 PIE 矢量表
    //服务例程(ISR)。
    //
    interrupt_initVectorTable();
    
    //
    //启用全局中断(INTM)和实时中断(DBGM)
    //
    EINT;
    ERTM;
    
    //
    //此示例中使用的中断被重新映射到
    //此文件中的 ISR 函数。
    //这在 PIE 矢量表中注册中断处理程序。
    //
    INTERRUPT_REGTER (INT_CANA0、&CANaISR);
    //中断寄存器(INT_CANB0、&CANbISR);
    //
    //启用 CAN-B 中断信号
    //
    INTERRUPT_ENABLE (INT_CANA0);
    //中断使能(INT_CANB0);
    //
    //设置 CAN_GLB_INT_EN 寄存器中的 GLBINT0_EN 位
    //
    CAN_enableGlobalInterrupt (CANA_base、CAN_GLOBAL_INT_CANINT0);
    //CAN_enableGlobalInterrupt (CANB_BASE、CAN_GLOBAL_INT_CANINT0);
    //
    //初始化用于发送 CAN 消息的发送消息对象。
    //消息对象参数:
    // CAN 模块:A
    // 消息对象标识号:1.
    // 消息标识符:0x95555555
    // 消息帧:扩展
    // 消息类型:发送
    // 消息 ID 掩码:0x0
    // 消息对象标志:无
    // 消息数据长度:4字节
    // 发送端不启用中断
    //
    CAN_setupMessageObject (CANA_base、TX_MSG_obj_ID、0x955555、
    CAN_MSG_FRAME_EXT、CAN_MSG_OBJ_TYPE_TX、0、
    CAN_MSG_OBJ_NO_FLAGS、MSG_DATA_LENGTH);
    
    //
    //初始化用于接收 CAN 消息的接收消息对象。
    //消息对象参数:
    // CAN 模块:B
    // 消息对象标识号:1.
    // 消息标识符:0x95555555
    // 消息帧:扩展
    // 消息类型:接收
    // 消息 ID 掩码:0x0
    // 报文对象标志:接收中断
    // 消息数据长度:4字节
    //
    CAN_setupMessageObject (CANA_base、RX_MSG_obj_ID、0x955555、
    CAN_MSG_FRAME_EXT、CAN_MSG_OBJ_TYPE_RX、0、
    CAN_MSG_OBJ_RX_INT_ENABLE、MSG_DATA_LENGTH);
    
    //
    //初始化要发送的发送消息对象数据缓冲区
    //
    txMsgData[0]= 0x12;
    txMsgData[1]= 0x34;
    txMsgData[2]= 0x56;
    txMsgData[3]= 0x78;
    txMsgData[4]= 0x01;
    txMsgData[5]= 0x02;
    txMsgData[6]= 0x03;
    txMsgData[7]= 0x04;
    //
    //启动 CAN 模块 A 和 B 操作
    //
    CAN_startModule (CANA_base);
    //CAN_startModule (CANB_BASE);
    
    //
    //将消息从 CAN-A 发送到 CAN-B
    //
    对于(I = 0;I < TXCOUNT;I++)
    {
    //
    //检查错误标志以查看是否发生错误
    //
    if (错误标志> 500)
    {
    asm (" ESTOP0");
    }
    
    //
    //验证传输的消息数是否等于的数量
    //发送新消息之前收到的消息
    //
    if (txMsgCount < rxMsgCount && rxMsgCount!= 0)
    {
    txMsgData[0]+= 0x01;
    txMsgData[1]+= 0x01;
    txMsgData[2]+= 0x01;
    txMsgData[3]+= 0x01;
    
    //
    //如果超过一个字节、则复位数据
    //
    if (txMsgData[0]> 0xFF)
    {
    txMsgData[0]= 0;
    }
    if (txMsgData[1]> 0xFF)
    {
    txMsgData[1]= 0;
    }
    if (txMsgData[2]> 0xFF)
    {
    txMsgData[2]= 0;
    }
    if (txMsgData[3]> 0xFF)
    {
    txMsgData[3]= 0;
    }
    CAN_sendMessage (CANA_base、TX_MSG_OBJ_ID、MSG_DATA_LENGTH、
    txMsgData);
    txMsgCount++;
    }
    //else
    //{
    // errorFlag = 1;
    //}
    
    //
    //在继续前延迟0.25秒
    //
    DEVICE_DELAY_US (250000);
    
    //
    //递增发送消息数据中的值。
    //
    }
    
    //
    //停止应用程序
    //
    asm (" ESTOP0");
    }
    
    //
    CAN B ISR -当中断为
    //时调用中断服务例程 在 CAN 模块 B 上触发。每个
    //将执行两次 接收到帧。
    // 第一次更改状态;第二次接收邮箱。
    //
    __interrupt void
    canaISR (void)
    {
    uint32_t status;
    
    //
    //读取 CAN-B 中断状态(在 CAN_INT 寄存器中)以找到
    //中断原因
    //
    状态= CAN_getInterruptCus层(CANA_base);
    
    //
    //如果原因是控制器状态中断,则获取状态。
    //在每次 ISR 执行的第一次迭代期间、状态= 0x8000、
    //这就是 CAN_ES!= 0x07。
    //
    if (status =CAN_INT_INT0ID_STATUS)
    {
    //
    //读取控制器状态。 这将返回状态字段
    //可以指示各种错误的错误位。 错误处理
    //本示例中不是为了简单起见。 请参阅
    // API 文档,了解有关错误状态位的详细信息。
    //读取此状态的操作将清除中断。
    //
    状态= CAN_getStatus (CANA_base);//返回 CAN_ES 值。
    //
    //现在的状态= 0x00000010,表示 RxOK。
    //
    
    //
    //检查是否发生错误。
    //
    if (((status &~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_MSK)&&
    ((STATUS &μ~(CAN_STATUS_RXOK))!= CAN_STATUS_LEC_NONE))
    {
    //
    //设置一个标志来指示可能发生的某些错误。
    //
    errorFlag++;//= 1;
    }
    }
    //
    //检查原因是否是 CAN-B 接收报文对象1。 将被跳过
    //执行每个 ISR 的第一次迭代中
    //
    否则、如果(status == RX_MSG_OBJ_ID)
    {
    //
    //获取收到的消息
    //
    CAN_readMessage (CANA_base、RX_MSG_obj_ID、rxMsgData);
    
    //
    //到达这一点意味着 RX 中断发生在上
    //报文对象1、报文 RX 完成。 清除
    //消息目标中断。
    //
    CAN_clearInterruptStatus (CANA_base、RX_MSG_OBJ_ID);
    
    //
    //递增计数器以跟踪已有多少消息
    //已收到。 在实际应用中、这可用于将标志设置为
    //指示何时接收到消息。
    //
    rxMsgCount++;
    
    //
    //由于接收到消息,请清除所有错误标志。
    //
    //errorFlag = 0;
    if (rxMsgData[0]== txMsgData[0]&& rxMsgData[1]==txMsgData[1]&& rxMsgData[2]=txMsgData[2]&& rxMsgData[3]==txMsgData[3])
    {
    memset (rxMsgData、0、sizeof (rxMsgData));
    }
    其他
    errorFlag++;//= 0;
    }
    //
    //如果发生意外导致中断的情况,这将对中断进行处理。
    //
    其他
    {
    //
    //可以在此处执行伪中断处理。
    //
    }
    
    //
    //清除 CAN 中断线的全局中断标志
    //
    CAN_clearGlobalInterruptStatus (CANA_base、CAN_GLOBAL_INT_CANINT0);
    
    //
    //确认位于组9中的此中断
    //
    interrupt_clearACKGroup (interrupt_ack_group9);
    } 

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

    您好、 Joseph、

    您能否帮助查看最新反馈? 谢谢你。

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

    尊敬的 Aki:

    很抱歉、没有机会调试这个。  我应在本周结束前作出答复。

    此致、

    Joseph

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

    Rizhao/Aki、您好、

            对延迟答复表示歉意。  您能否验证应用程序中是否设置了 MSG_OBJ_USE_ID_FILTER。  有一个类似的帖子、我对邮件 ID 筛选中的同一问题做出了回应。  我认为这里也是如此。  这是帖子:

    https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/904797

    此致、

    Joseph

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

    Rizhao/Aki、您好、

    当您有机会时,请进行以下更改以允许接收来自所有 ID 的消息:

        CAN_setupMessageObject(CANA_BASE, RX_MSG_OBJ_ID, 0x95555555,
                               CAN_MSG_FRAME_EXT, CAN_MSG_OBJ_TYPE_RX, 0,
                               CAN_MSG_OBJ_RX_INT_ENABLE|CAN_MSG_OBJ_USE_ID_FILTER, MSG_DATA_LENGTH);
    添加 CAN_MSG_OBJ_USE_ID_FILTER 将允许进行消息过滤、并且由于掩码设置为"0"、因此将接收来自其他 ID 的消息。  这将解决您的第二个问题。  尝试执行此操作、查看 ID 问题是否得到解决、然后可以调试有关 CAN 状态的第一个问题。
    此致、
    Joseph
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Joseph、

    非常感谢您的建议、 这个问题可以解决。

    此致、

    Rizhao.Qin

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

    您好、Joseph、

    感谢您的大力支持!