2. CAN总线基础:物理层特性、数据帧结构、总线仲裁机制
好,咱们正式开始聊CAN总线。说实话,我接触CAN总线快二十年了,从最早的CAN 2.0A到现在的CAN FD,底层这些东西其实一直没怎么变。你只要把物理层、数据帧和仲裁机制这三块吃透了,后面学UDS诊断就会轻松很多。
2.1 CAN物理层特性
CAN总线是差分信号传输,说白了就是两根线:CAN_H和CAN_L。为什么用差分?抗干扰能力强啊。我在做车载项目时,发动机舱里电磁环境那么恶劣,差分信号照样稳得很。
物理层有几个关键参数,我列个表给你看:
| 参数 | 典型值 | 说明 |
|---|---|---|
| 总线电平 | 显性:CAN_H≈3.5V,CAN_L≈1.5V 隐性:CAN_H≈2.5V,CAN_L≈2.5V |
显性电平代表逻辑0,隐性代表逻辑1 |
| 传输速率 | 125kbps ~ 1Mbps | 高速CAN常用500kbps,低速CAN用125kbps |
| 总线长度 | 与速率相关,1Mbps时最长约40m | 速率越低,距离越远 |
| 终端电阻 | 120Ω(两端各一个) | 防止信号反射 |
重点记住:显性电平(0)会覆盖隐性电平(1)。这个特性是后面仲裁机制的基础。
嗯,这里有个坑我得提醒你。终端电阻一定要加在总线两端,不是随便找个地方焊上去就行。我曾经见过一个项目,工程师把120Ω电阻焊在了一个节点内部,结果总线信号反射得一塌糊涂,通讯时好时坏。排查了整整两天才找到原因。
2.2 CAN数据帧结构
CAN总线上一共就四种帧:数据帧、远程帧、错误帧、过载帧。咱们做UDS诊断,打交道最多的就是数据帧。来,我带你拆开看看。
一个标准CAN数据帧(CAN 2.0A)长这样:
SOF + 11位ID + RTR + IDE + r0 + DLC + 数据段(0-8字节) + CRC + ACK + EOF
每个字段的含义:
- SOF(Start of Frame):1位显性电平,告诉所有节点“我要发数据了”
- ID(标识符):11位,决定消息优先级。数值越小优先级越高
- RTR(Remote Transmission Request):区分数据帧(0)和远程帧(1)
- IDE(Identifier Extension):标准帧为0,扩展帧为1
- DLC(Data Length Code):4位,表示数据字节数(0-8)
- 数据段:0-8字节,UDS诊断报文就放在这里
- CRC:15位校验码,保证数据完整性
- ACK:应答位,接收节点拉低表示收到
- EOF:7位隐性电平,帧结束标志
我的经验:做UDS诊断时,ID字段特别重要。比如0x7DF是诊断请求的广播ID,0x7E8是ECU的响应ID。这些ID值在ISO 15765-2里有明确规定,千万别搞混。
扩展帧(CAN 2.0B)的ID是29位,结构稍微复杂一点:
SOF + 11位基础ID + SRR + IDE + 18位扩展ID + RTR + r1 + r0 + DLC + 数据段 + CRC + ACK + EOF
我个人习惯在项目里优先用标准帧,除非ID不够用了才上扩展帧。为什么?标准帧的仲裁效率更高,总线利用率也更好。
2.3 CAN总线仲裁机制
仲裁机制是CAN总线最巧妙的设计之一。你想想看,多个节点同时发数据怎么办?总线上又没有“中央调度员”。
CAN的解决方案很简单:逐位仲裁,谁优先级高谁发。
具体过程是这样的:
- 所有要发送的节点同时发出SOF位(显性),同步开始
- 接着逐位发送ID,从最高位(MSB)开始
- 每个节点发送一位后,马上回读总线电平
- 如果自己发的是隐性(1),但读到的是显性(0),说明有更高优先级的节点在发,自己立即退出
- 最后剩下的那个节点,就是ID最小的那个,继续发送剩余数据
核心原理:显性电平(0)覆盖隐性电平(1)。ID越小,显性位出现得越早,优先级越高。
举个例子:节点A的ID是0x100,节点B的ID是0x200。二进制分别是:
A: 001 0000 0000
B: 010 0000 0000
从最高位开始比。第1位都是0,平手。第2位A是0(显性),B是1(隐性)。B读到总线上是0,知道自己输了,乖乖退出。A继续发。
避坑指南:我曾经遇到过一个问题,两个ECU的ID设成了相同的值。结果每次同时发送时,仲裁机制无法区分,数据一直出错。排查了很久才发现是ID冲突。所以项目里一定要做好ID分配管理,别偷懒。
仲裁机制的好处很明显:
- 不需要额外的总线仲裁器,硬件自动完成
- 高优先级消息的延迟是确定的,适合实时控制
- 没有数据丢失,输了的节点自动重发
但也要注意一点:总线负载率不能太高。我一般控制在30%以下,超过50%就要小心了。负载太高时,低优先级消息可能一直发不出去,这就是所谓的“饿死”现象。做UDS诊断时,如果诊断报文优先级设得太低,可能会被其他控制报文一直抢占,导致诊断超时。
好了,CAN总线的基础就这些。物理层决定了信号怎么传,数据帧决定了消息长什么样,仲裁机制决定了谁先说话。这三块搞明白了,后面学UDS诊断的传输层和应用层,你就知道为什么诊断报文要那样设计了。