Arduino双MCP2515双CAN总线双向转发出现消息回环问题求解
MCP2515双向CAN转发读取异常解决方案
问题根因
你遇到的问题是MCP2515的默认回显机制导致的:MCP2515默认工作模式下,自身发送到CAN总线上的报文,会被自己的接收缓冲区回收,相当于你给CAN2发的报文,立刻被CAN2对应的MCP2515自己收到了,挤占了接收队列,导致你读不到CAN2总线上原本的其他报文。
无需记录已发送报文的解决方案
方案1:关闭MCP2515的自收发回显
你使用的mcp_can库支持直接配置MCP2515的工作模式,在初始化CAN总线的函数末尾添加配置,禁用两个MCP2515的自收发回显即可:
void initCanBus() { while (CAN_CAR.begin(CAN_500KBPS, MCP_8MHz) != CAN_OK) {} while (CAN_PDC.begin(CAN_500KBPS, MCP_8MHz) != CAN_OK) {} // 新增配置,设置为不回显的正常工作模式 CAN_CAR.setMode(MCP_NORMAL); CAN_PDC.setMode(MCP_NORMAL); }
如果你用的库版本没有封装setMode接口,可以直接操作寄存器实现:
CAN_CAR.writeRegister(MCP_CANCTRL, 0x00); CAN_PDC.writeRegister(MCP_CANCTRL, 0x00);
方案2:优化接收逻辑,增加接收缓冲区
你的现有代码是单条接收单条转发,没有缓冲机制,一旦转发延迟就会丢包,你可以给两路CAN各加一个环形缓冲区:
- 分别定义两个结构体存储报文ID、长度、8字节数据
- 定义对应的环形队列,先把所有收到的报文全部存入队列,再统一处理转发
- 优先执行接收逻辑,确保总线上的报文不会因为转发操作被丢弃
方案3:改用中断触发接收
如果你给两个MCP2515的INT引脚连接了Arduino的外部中断,可以用中断触发报文接收,替代现在的轮询checkReceive逻辑,中断接收的优先级更高,能避免回显报文抢占真实报文的接收时机。
现有代码隐藏问题修正
你当前的转发逻辑硬编码了发送长度为8,应该替换为读取到的实际报文长度,避免发送多余的脏数据:
// 修正CAN1转CAN2的发送逻辑 CAN_PDC.sendMsgBuf(carAddress, 0, carLength, carDataBuffer); // 修正CAN2转CAN1的发送逻辑 CAN_CAR.sendMsgBuf(pdcAddress, 0, pdcLength, pdcDataBuffer);
内容的提问来源于stack exchange,提问作者billy gates
相关产品推荐
相关产品推荐

