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.
工具/软件: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);
您好、Joseph、
非常感谢您的建议、 这个问题可以解决。
此致、
Rizhao.Qin
您好、Joseph、
感谢您的大力支持!