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小,谁就赢。
具体怎么仲裁的?
- 所有节点同时发送SOF,总线进入同步状态。
- 接着,每个节点逐位发送自己的ID。从最高位(MSB)开始。
- CAN总线是“线与”逻辑:显性位(0)会覆盖隐性位(1)。
- 如果一个节点发送了隐性位(1),但总线上检测到显性位(0),它就知道自己仲裁输了,立刻停止发送,转为接收模式。
- 仲裁赢的节点继续发送剩余数据,整个过程没有数据丢失。
举个例子:节点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网络的物理层设计和终端匹配,那才是真正考验硬件功底的地方。