公司动态
第322篇 CAN总线深入解析
上篇对比了SPI/I2C/UART/CAN四种协议。这篇深入CAN总线——在机器人领域CAN是电机驱动和多轴协调的事实标准。面试中CAN相关的题目深度往往超出预期不只是知道CAN是什么而是帧格式、错误处理、总线调度这些细节。CAN帧结构一个标准CAN数据帧由以下部分组成帧起始SOF1位→ 仲裁段12位11位IDRTR→ 控制段6位IDERTRDLC→ 数据段0-8字节→ CRC段15位CRC1位分隔符→ ACK段2位→ 帧结束7位。几个关键细节DLCData Length Code表示数据长度0-8字节。CAN FD扩展到0-64字节。RTRRemote Transmission Request位用于远程帧——请求另一个节点发送数据。远程帧没有数据段。CRC是15位CRC-15生成多项式为X^15X^14X^10X^8X^7X^4X^31。硬件自动计算和校验。ACK槽。发送节点发隐性位1接收节点在ACK槽发显性位0。如果发送节点检测到隐性位说明没有节点正确接收触发错误处理。CAN的位时序也值得了解。每个CAN位被分为多个时间段同步段SS、传播段Prop、相位缓冲段1PBS1和相位缓冲段2PBS2。采样点的位置通常在75%-87.5%处影响通信的稳定性。采样点太靠前容易受干扰太靠后容错能力差。CiA推荐在75%处但很多实际系统用87.5%。配置位时序参数SJW、TSEG1、TSEG2时要确保所有节点的采样点位置一致否则在高负载时会出现错误。CAN的仲裁机制CAN的仲裁是其最精妙的设计。多个节点同时发送时所有节点在SOF后开始逐位发送ID每个节点在发送隐性位1的同时检测总线电平如果检测到显性位0说明有更高优先级的节点在发送该节点退出仲裁转为接收状态等当前帧结束后再尝试发送仲裁是非破坏性的——胜出节点的帧完整发送没有任何延迟或数据损坏。ID值越小优先级越高因为显性位0优先。这个机制有一个重要推论如果你需要保证某个消息的实时性给它分配一个较小的ID。在机器人中急停信号、关节位置反馈这些高实时性消息应该用低ID。错误处理机制CAN有五种错误类型位错误Bit Error发送节点检测到的总线电平与发送的位不一致填充错误Fill Error连续6个相同极性的位违反位填充规则CRC错误接收到的CRC与计算值不匹配格式错误Form Error固定格式字段中出现非法位ACK错误ACK槽中没有检测到显性位每个CAN节点维护两个错误计数器TEC发送错误计数器和REC接收错误计数器。根据计数器值节点处于三种状态Error ActiveTEC128且REC128正常参与通信Error PassiveTEC≥128或REC≥128可以收发但发送错误帧时延迟发送Bus OffTEC≥256断开总线不参与任何通信Bus Off后节点需要等待128个11位隐性时间约1.28ms1Mbps才能尝试恢复。这个机制保证了故障节点不会持续干扰总线。错误帧的结构也值得了解。错误帧由错误标志6个连续相同极性位违反位填充规则和错误分隔符8个隐性位组成。叠加错误多个节点同时发错误帧时隐性位会被显性位覆盖形成叠加原则——确保所有检测到错误的节点都知道有其他节点也检测到了错误。这种设计让错误处理本身也是非破坏性的。CAN FD经典CAN的升级CAN FDFlexible Data-rate解决了经典CAN的两个痛点数据段最大8字节太小带宽利用率不够。CAN FD的改进数据段最大64字节8/12/16/20/24/32/48/64仲裁段用标称比特率比如500kbps数据段切换到更高比特率比如2Mbps或5Mbps改进的CRCCRC-17用于≤16字节CRC-21用于16字节去掉了远程帧实际项目中几乎不用CAN FD与经典CAN在物理层兼容同样的差分线但CAN FD控制器可以处理两种帧。混合部署时需要注意经典CAN节点无法理解CAN FD帧的BRS位会把它当作错误。解决方案是CAN FD网络中不混入经典CAN节点或者用网关隔离。CAN FD的实际部署建议数据段切换到高速率时对布线质量要求更高。如果线缆质量不好或者分支太长高速段可能出现信号完整性问题。经验法则是仲裁段500kbps、数据段2Mbps是大多数线缆能稳定工作的组合。如果要用5Mbps或8Mbps需要用专用线缆并严格控制分支长度每个stub不超过0.3米。另外CAN FD的CRC-21比经典CAN的CRC-15更强错误检测率提高了约100倍——这对安全性要求高的应用比如协作机器人很重要。CAN在机器人中的应用在机器人中CAN主要用于电机驱动器的通信。典型的架构一个主控制器比如运行ROS2的工控机通过USB-CAN适配器连接到CAN总线总线上挂着6-12个电机驱动器。通信协议通常是主从式主控制器周期性地发送控制指令目标位置/速度/力矩各驱动器回复状态反馈实际位置/电流/温度。常见的开源协议有CANopen工业标准基于CAN的应用层协议定义了对象字典、PDO过程数据对象、SDO服务数据对象CiA 402基于CANopen的驱动器配置文件定义了状态机和控制字ODrive、Moteus、MIT的mini-cheetah驱动器都使用自定义的CAN协议但核心思路类似简洁的命令帧状态反馈帧周期1ms。自定义CAN协议的设计原则第一尽量用标准帧11位ID不要用扩展帧29位ID因为扩展帧的开销更大且很多工具支持不好。第二数据对齐用整型而不是浮点——CAN总线上没有标准化的浮点编码把角度乘以1000传整数毫度精度比传IEEE754浮点数更可靠。第三心跳机制是必须的——主控制器周期性发送心跳帧驱动器超过一定时间没收到就进入安全状态通常是零力矩模式。第四紧急停止用最高优先级ID确保在任何总线负载下都能及时传达。面试要点CAN为什么用差分信号。差分信号抗共模干扰——外部电磁干扰同时耦合到CAN_H和CAN_L上接收端只检测两者的电压差共模噪声被抵消。这就是为什么CAN可以在工业环境中稳定工作。CAN总线的终端电阻。两端各120Ω并联后60Ω。这是为了匹配双绞线的特性阻抗约60-120Ω防止信号在末端反射。如果总线很长或分支很多可能需要额外的终端电阻。位填充bit stuffing的作用。CAN协议规定连续5个相同极性的位后必须插入一个相反极性的位。这保证了足够的信号跳变密度让接收端的时钟恢复电路能正确同步。接收端自动去除填充位。CAN总线的最大负载率。面试中可能问你1Mbps的CAN总线理论最大帧率是多少一个标准数据帧8字节数据约111位加上帧间间隔3位每秒最多约1Mbps÷114≈8772帧。实际中总线负载率建议不超过70%——超过后仲裁延迟急剧增加实时性无法保证。给你的建议如果你要深入学习CAN建议从CANopen开始。CANopen虽然复杂但它展示了如何在CAN上构建完整的应用层协议——NMT网络管理、PDO实时数据、SDO配置参数、EMCY紧急报文。理解了CANopen再写自定义协议就很简单了。调试CAN问题需要工具。入门级用USB-CAN适配器比如CANable几十美元配合PCAN-View或BusMaster软件抓包分析。专业级用Vector的CANoe或PCAN支持总线负载分析、错误帧统计、DBC文件解析。DBC文件是CAN数据库的描述文件定义了每个ID的含义和信号布局是多节点协作的基础。最后一个建议在写CAN驱动之前先用现成的工具把协议跑通。用PCAN-View手动发送帧确认硬件连接和波特率正确再写代码。很多CAN通信问题其实是硬件层面的——终端电阻没接、线序接反、波特率不匹配。先排除硬件问题再写软件能省很多时间。上一篇第321篇 嵌入式通信协议SPI/I2C/UART/CAN下一篇预告第323篇 EtherCAT工业以太网协议