2、CAN总线基础:CAN协议原理

好,咱们正式开始聊CAN总线。说实话,CAN总线是我入行车载网络接触的第一个协议,也是到目前为止,我认为最经典的一个。它诞生于上世纪80年代,由Bosch公司发明,初衷是为了解决汽车内部线束过多的问题。你想想看,当年一辆豪华车里的线束能绕地球好几圈(夸张了点),CAN的出现,直接让这些线束瘦身成功。

这一节,我会把CAN协议的核心原理掰开揉碎了讲给你听。包括帧结构、仲裁机制、错误处理,还有CAN 2.0和CAN FD的区别,最后咱们算一算CAN网络的带宽。嗯,内容不少,但都是硬货。

2.1 CAN协议原理:帧结构

CAN总线上的数据,是以“帧”为单位传输的。就像你寄快递,得有个包裹,包裹上写清楚地址、内容、校验信息。CAN帧也一样,结构非常严谨。

咱们先看最常用的数据帧。它分为标准帧和扩展帧,区别在于ID的长度。标准帧的ID是11位,扩展帧是29位。我个人习惯,在项目初期能选标准帧就选标准帧,因为帧头短,效率高。除非节点太多,ID不够用了,才上扩展帧。

一个标准数据帧长这样:

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

我来拆解一下关键字段:

  • SOF(Start of Frame):帧起始,一个显性位,告诉总线上所有节点:“我要发数据了!”
  • ID(Identifier):标识符,11位。它不光标识消息的“身份”,还决定了消息的优先级。ID越小,优先级越高。
  • RTR(Remote Transmission Request):远程帧标志。数据帧里RTR=0,远程帧里RTR=1。这个字段在数据帧里基本就是0。
  • DLC(Data Length Code):数据长度码,4位,表示数据场有多少个字节。范围是0~8。注意,DLC可以表示0~8,但CAN 2.0最多只能带8字节数据。
  • Data Field:数据场,0~8字节。这就是你要传的实际数据。
  • CRC(Cyclic Redundancy Check):循环冗余校验,15位。用来检测传输过程中有没有比特错误。
  • ACK(Acknowledge):应答位。发送节点发完数据后,会释放总线,接收节点如果正确收到,就在这个位拉低总线(显性),告诉发送方:“我收到了!”
  • EOF(End of Frame):帧结束,7个隐性位。

重点提醒:CAN帧里没有源地址和目的地址!它是基于消息ID的广播式通信。任何节点都可以发,任何节点都可以收。你只需要配置好接收过滤器,只收你关心的ID就行。

我在项目中遇到过一个问题:有个同事把DLC设成了8,但数据场只填了4个有效字节,剩下4个是随机值。结果接收方解析数据时,把随机值当成了有效信号,导致车辆误动作。嗯,从那以后,我要求团队必须严格按实际数据长度设置DLC,多余字节必须清零。

2.2 仲裁机制:谁先说话?

CAN总线是多主总线,意思是任何节点都可以随时往总线上发数据。那问题来了:如果两个节点同时发,总线会不会打架?

不会。CAN的仲裁机制非常巧妙,它用的是无损逐位仲裁。说白了,就是大家同时发,谁的ID小,谁就赢。

具体怎么仲裁的?

  1. 所有节点同时发送SOF,总线进入同步状态。
  2. 接着,每个节点逐位发送自己的ID。从最高位(MSB)开始。
  3. CAN总线是“线与”逻辑:显性位(0)会覆盖隐性位(1)。
  4. 如果一个节点发送了隐性位(1),但总线上检测到显性位(0),它就知道自己仲裁输了,立刻停止发送,转为接收模式。
  5. 仲裁赢的节点继续发送剩余数据,整个过程没有数据丢失。

举个例子:节点A的ID是0x100(二进制0001 0000 0000),节点B的ID是0x200(二进制0010 0000 0000)。从最高位开始比,第1位都是0,第2位A是0,B是1。A发0(显性),B发1(隐性),总线被A拉成0,B检测到总线与自己发送的不一致,B退出。A胜出。

个人经验:设计ID分配时,一定要把高优先级消息(比如刹车、转向)分配小ID,低优先级消息(比如车窗、空调)分配大ID。我曾经见过一个项目,把车窗的ID设得比刹车还小,结果刹车信号被车窗信号堵住了,差点出事。切记,ID越小,优先级越高!

2.3 错误处理:CAN的自我修复能力

CAN总线之所以在汽车领域屹立不倒,强大的错误处理能力是核心原因之一。它有一套完整的错误检测和恢复机制,保证数据不会“烂”在总线上。

CAN定义了5种错误类型:

  • 位错误(Bit Error):发送节点在发送位的同时,监控总线电平。如果检测到的电平与自己发送的不一致,就报位错误。注意,仲裁期间和ACK位除外。
  • 填充错误(Stuff Error):CAN使用位填充规则——连续发送5个相同电平后,必须插入一个相反电平。如果接收节点检测到连续6个相同电平,就报填充错误。
  • CRC错误(CRC Error):接收节点计算的CRC与发送节点附带的CRC不一致,报CRC错误。
  • 形式错误(Form Error):帧的固定格式位(如CRC分隔符、ACK分隔符、EOF)必须是隐性位,如果检测到显性位,报形式错误。
  • 应答错误(ACK Error):发送节点在ACK槽没有检测到显性位(说明没有节点接收成功),报应答错误。

每个节点都有两个计数器:发送错误计数器(TEC)接收错误计数器(REC)。错误发生一次,计数器加1;正确收发一次,计数器减1。根据计数器的值,节点会处于三种状态之一:

状态 条件 行为
主动错误(Error Active) TEC < 127 且 REC < 127 正常通信,检测到错误时发送主动错误标志(6个显性位)
被动错误(Error Passive) TEC > 127 或 REC > 127 可以通信,但检测到错误时只能发送被动错误标志(6个隐性位),且发送前要等待8个隐性位
总线关闭(Bus Off) TEC > 255 完全断开与总线的连接,不再参与任何通信

避坑指南:我曾经调试过一个项目,某个节点频繁报错,最后发现是它的CAN收发器供电不稳,导致发送的电平信号畸变,被其他节点误判为位错误。这个节点反复重试,TEC一路飙升到255,最终总线关闭。排查了整整两天才找到原因。所以,硬件供电质量对CAN通信的稳定性至关重要,别光盯着软件看。

2.4 CAN 2.0与CAN FD的区别

CAN 2.0是经典版本,分为CAN 2.0A(标准帧)和CAN 2.0B(扩展帧)。它最大的限制是:数据场最多8字节,波特率最高1Mbps

随着汽车电子功能越来越复杂,8字节显然不够用了。比如OTA升级、ADAS传感器数据,动不动几十上百字节。于是,CAN FD(Flexible Data-Rate)应运而生。

CAN FD和CAN 2.0的主要区别:

特性 CAN 2.0 CAN FD
最大数据长度 8字节 64字节
波特率 最高1Mbps 数据段最高8Mbps(仲裁段仍为1Mbps)
帧格式 固定 新增FDF、BRS、ESI位
CRC 15位 17位(数据≤16字节)或21位(数据>16字节)
兼容性 CAN FD节点可以兼容CAN 2.0,反之不行

CAN FD最巧妙的设计是双波特率:仲裁段仍然用1Mbps(保证与CAN 2.0兼容),但数据段可以切换到更高的速率(比如2Mbps、5Mbps甚至8Mbps)。切换点就在BRS位(Bit Rate Switch)。

我个人建议,如果你的项目还在用CAN 2.0,但未来有升级需求,硬件上直接选支持CAN FD的控制器。成本差不了多少,但后续升级空间大很多。我手头一个项目,最初设计时用了CAN 2.0,后来要加一个高分辨率雷达,数据量暴增,不得不把整个网络升级到CAN FD,板子都得重新画,教训深刻。

2.5 CAN网络带宽计算

好,最后咱们来算算CAN网络的带宽。说白了,就是一条CAN总线每秒能传多少数据。

带宽的计算公式很简单:

有效带宽 = (数据位数量 / 总帧位数) × 波特率

咱们以标准数据帧为例,假设波特率500kbps,数据场8字节:

  • 总帧位数:SOF(1) + ID(11) + RTR(1) + IDE(1) + r0(1) + DLC(4) + Data(64) + CRC(15) + CRC分隔符(1) + ACK(1) + ACK分隔符(1) + EOF(7) = 108位
  • 但别忘了位填充!CAN规定连续5个相同电平后要插入一个相反位。假设数据随机,位填充开销约为20%。实际帧长 ≈ 108 × 1.2 = 129.6位
  • 有效数据位:64位(8字节)
  • 有效带宽 = (64 / 129.6) × 500kbps ≈ 246.9kbps

你看,标称500kbps的CAN总线,实际有效带宽只有一半左右。这就是协议开销和位填充带来的代价。

再算算CAN FD,同样500kbps仲裁段,数据段切换到2Mbps,数据场64字节:

  • 仲裁段帧头:SOF(1) + ID(11) + RTR(1) + IDE(1) + FDF(1) + BRS(1) + ESI(1) + DLC(4) = 21位
  • 数据段:Data(512) + CRC(21) + CRC分隔符(1) = 534位
  • 帧尾:ACK(1) + ACK分隔符(1) + EOF(7) = 9位
  • 总时间 = 21位/500kbps + 534位/2Mbps + 9位/500kbps = 42μs + 267μs + 18μs = 327μs
  • 有效带宽 = 512位 / 327μs ≈ 1.56Mbps

结论:同样是500kbps的仲裁段,CAN FD通过提高数据段速率和增加数据长度,有效带宽从CAN 2.0的约247kbps提升到了1.56Mbps,提升了6倍多。这就是为什么现在新车都在往CAN FD迁移。

嗯,这一节的内容就到这里。CAN总线虽然“老”,但它的设计思想至今仍在影响车载网络。下一节,咱们聊聊CAN网络的物理层设计和终端匹配,那才是真正考验硬件功底的地方。