3. CAN/CAN FD总线:从原理到实战

大家好,我是老张。今天咱们聊聊CAN总线。

说实话,在车载网络里,CAN总线就像老黄牛。它不花哨,但可靠。我从2008年开始接触CAN,那时候还在做车身控制。后来做智能驾驶,发现CAN依然是底盘和动力域的核心。你想想看,一辆L3级以上的智能车,CAN节点轻松超过50个。不懂CAN,你根本没法做系统集成。

3.1 CAN协议原理:为什么它能活30年?

CAN协议是1986年由Bosch发明的。为什么能活到现在?核心就两点:实时性可靠性

先看帧结构。标准CAN帧长这样:

SOF + 11位ID + RTR + IDE + r0 + 4位DLC + 0~8字节数据 + 15位CRC + ACK + EOF

这里我重点说三个东西:

  • ID(标识符):它不表示地址,而是表示优先级。ID越小,优先级越高。我在项目中见过有人把转向信号ID设成0x700,结果被一堆0x100的报文堵死。嗯,这是个坑。
  • CSMA/CA + 非破坏性仲裁:这是CAN的精髓。多个节点同时发送时,ID小的自动获胜。说白了,就是谁急谁先走。
  • CRC校验:15位CRC,加上位填充机制。误码率低到10^-12级别。我做过统计,在实车环境下,CAN的误帧率大概在0.01%以下。

核心结论:CAN的可靠性来自物理层的差分信号 + 数据链路层的CRC + 应用层的重传机制。三层防护,缺一不可。

3.2 CAN FD升级点:为什么我们需要它?

传统CAN的瓶颈很明显:8字节数据,1Mbps速率。智能驾驶时代,这不够用了。

CAN FD(Flexible Data-rate)做了两件事:

  1. 数据场扩展到64字节:原来只能传8个字节,现在可以传64个。比如高精地图的局部更新、雷达点云的压缩数据,都能塞进去了。
  2. 速率翻倍:仲裁段保持1Mbps(兼容CAN),数据段可以跑到5Mbps甚至8Mbps。我在某Tier1的项目里,把CAN FD的数据段设成了5Mbps,效果很好。

但要注意,CAN FD不是简单的「提速」。它改了帧格式:

SOF + 11/29位ID + BRS + ESI + DLC + 0~64字节数据 + 17/21位CRC + ACK + EOF

这里多了两个关键位:

  • BRS(Bit Rate Switch):1表示数据段切换到高速模式,0表示保持原速。
  • ESI(Error State Indicator):发送节点是否处于被动错误状态。

我的建议:如果你在做新项目,直接上CAN FD。成本增加不到5%,但带宽提升4倍以上。别再用传统CAN了,真的。

3.3 CAN网络设计要点:实战中的血泪教训

这部分我直接上干货。设计一个可靠的CAN网络,你需要注意这几点:

设计项 要求 我的经验
终端电阻 120Ω ± 1%,两端各一个 我见过有人用100Ω,结果信号反射严重,丢帧率飙升到5%
总线长度 1Mbps时 ≤ 40m 实际项目中,我建议控制在30m以内,留余量
节点数量 ≤ 30个(标准CAN) 超过30个,建议用CAN FD或加网关
线缆类型 双绞线,特性阻抗120Ω 别用普通电线,我吃过亏
共模扼流圈 建议加在节点入口 能有效抑制EMI,特别是电机控制器附近

还有一个容易被忽略的点:CAN_H和CAN_L的电压。正常工作时,CAN_H约3.5V,CAN_L约1.5V。如果你量出来CAN_H只有2.5V,CAN_L也是2.5V,那说明总线处于隐性状态,没有节点在发送。如果CAN_H和CAN_L都是0V,那大概率是短路了。

3.4 我在实车调试中遇到的CAN错误帧问题

这部分我多说几句。实车调试和台架测试完全是两码事。台架上跑得好好的,一上车就出问题,这种事我遇到太多次了。

案例1:CRC错误导致的间歇性丢帧

有一次,某款车的转向角传感器每隔几分钟就丢一帧。我查了三天,最后发现是线束过长(超过50m)加上终端电阻没焊好。信号反射导致CRC校验失败。解决办法:换短一点的线束,重新焊接120Ω电阻。

案例2:位填充错误

CAN协议规定,连续5个相同电平后必须插入一个相反电平。如果发送节点的晶振偏差太大(超过1%),就会导致位填充错误。我在某项目里遇到过,一个国产MCU的CAN控制器晶振偏差达到2.3%,结果整车网络里全是错误帧。最后换了晶振,问题解决。

案例3:ACK错误

这个最常见。发送节点发出报文后,没有收到ACK应答。原因通常是接收节点的CAN控制器没配置好,或者接收节点掉电了。我建议你在调试时,用CANalyzer或PCAN抓一下ACK位,看看是不是每个报文都有应答。

避坑指南:我曾经在实车调试中,因为一个节点的CAN控制器进入了Bus Off状态,导致整个网络瘫痪了10秒钟。后来我养成了一个习惯:每个节点的错误计数器都要监控。一旦发现TEC(发送错误计数)超过127,立刻报警。

最后,我画了一张CAN错误帧的排查流程图,方便你对照着查问题:

CAN错误帧排查流程图 发现错误帧 步骤1:检查CAN_H/CAN_L电压 电压正常? 检查线束/终端电阻 步骤2:抓取错误帧类型 CRC错误? 检查信号反射/线束 检查ACK/位填充 定位并修复

这张图的核心逻辑是:先看物理层(电压),再看数据链路层(CRC、ACK、位填充)。别一上来就怀疑软件,很多时候问题出在线上。

好了,CAN总线这部分就聊到这儿。记住一句话:CAN不复杂,但细节决定成败。下次你在调试中遇到错误帧,别慌,按流程一步步查,总能找到原因。


公众号:蓝海资料掘金营,微信deep3321