3、CAN总线基础:CAN总线物理层、差分信号、CAN帧结构
各位同学,今天我们来聊聊CAN总线的基础。说实话,CAN总线在汽车电子里,就像人的神经系统一样重要。我做了这么多年汽车电子,处理过最多的通信问题,十有八九都跟CAN有关。咱们今天就把它的底裤扒干净,从物理层到帧结构,一个一个说清楚。
3.1 CAN总线物理层:为什么它能扛造?
先说说物理层。CAN总线用的是两根线——CAN_H和CAN_L。你想想看,车里的环境多恶劣?发动机点火、空调压缩机启停、各种电机干扰,普通通信线早就废了。但CAN总线能活得好好的,为什么?
说白了,它用了差分信号传输。两根线绞在一起,信号是成对出现的。干扰来了,两根线上同时被干扰,但它们的差值基本不变。这就叫共模抑制。
核心要点:CAN总线物理层采用差分双绞线,抗干扰能力强,适合车载恶劣电磁环境。
我记得有一次,一个客户的车在EMC测试时总不过。查来查去,发现是CAN线没有绞合,直接平行走线。我建议他把线换成双绞线,问题立马解决。嗯,这里要注意:CAN线的绞距也是有讲究的,一般每米绞20-30圈比较合适。
3.2 差分信号:CAN的看家本领
差分信号怎么工作的?我简单说:
- 显性电平(Dominant):CAN_H比CAN_L高2V左右。这时候总线被拉低,逻辑上表示"0"。
- 隐性电平(Recessive):CAN_H和CAN_L电压相等,约2.5V。逻辑上表示"1"。
你可能会问:为什么显性是0,隐性是1?这是CAN协议规定的。显性电平可以覆盖隐性电平,这就实现了总线仲裁。后面我们会细说。
实战经验:我在调试时,习惯用示波器同时看CAN_H和CAN_L。如果两根线波形完全对称,说明物理层没问题。如果出现不对称,八成是终端电阻坏了或者线缆断了。
差分信号还有个好处:它不依赖地线。两个节点之间即使地电位有差异,只要差值在-2V到+7V范围内,通信照样正常。这在车上太重要了——不同ECU的地电位很难完全一致。
3.3 CAN帧结构:一帧数据长什么样?
好了,物理层说完了,咱们看看数据是怎么打包的。CAN帧结构,我建议你把它当成一个快递包裹来理解。
一个标准CAN数据帧,由以下几个部分组成:
| 字段 | 长度 | 说明 |
|---|---|---|
| SOF | 1 bit | 帧起始,显性电平,告诉所有节点"我要发数据了" |
| ID | 11 bits(标准帧) | 标识符,决定优先级,数值越小优先级越高 |
| RTR | 1 bit | 远程帧标志,0表示数据帧,1表示远程帧 |
| IDE | 1 bit | 扩展帧标志,0表示标准帧 |
| r0 | 1 bit | 保留位 |
| DLC | 4 bits | 数据长度,0-8字节 |
| Data | 0-64 bits | 实际数据,最多8字节 |
| CRC | 15 bits | 循环冗余校验,检测传输错误 |
| ACK | 2 bits | 应答场,接收节点确认收到 |
| EOF | 7 bits | 帧结束,隐性电平 |
我一个个拆开讲。
3.3.1 SOF(帧起始)
SOF就是一个显性位。总线空闲时是隐性电平,SOF一出现,所有节点都知道:有人要说话了。这就像开会时有人举手说"我来讲两句"。
3.3.2 ID(标识符)
ID是CAN帧的灵魂。它决定了这条消息的优先级。数值越小,优先级越高。为什么?因为ID高位先发,谁先发显性位谁就赢。
避坑指南:我曾经遇到过一个问题:两个ECU用同一个ID发数据,结果总线乱套了。记住:CAN总线上每个ID只能有一个发送者。虽然接收者可以多个,但发送者必须唯一。
3.3.3 DLC(数据长度码)
DLC告诉接收方:我要发多少数据。范围是0到8。注意:DLC可以设为0,这时候Data字段为空,但帧结构依然完整。我见过有人用DLC=0的帧做心跳包,只为了告诉其他节点"我还活着"。
3.3.4 Data(数据段)
这就是真正的数据了。最多8个字节。你可能会问:为什么只有8个字节?因为CAN总线设计之初,考虑的是实时性。数据太长会占用总线太久,影响其他节点。8个字节对于控制类信号(车速、转速、油门位置)完全够用。
如果数据超过8个字节怎么办?那就用CAN FD(灵活数据速率),它支持最多64字节。不过那是后面章节的内容了。
3.3.5 CRC(循环冗余校验)
CRC是15位的校验码。发送方根据前面的数据算出一个值,接收方收到后重新算一遍。如果对不上,说明传输有误,接收方就不发ACK。
我习惯用CAN分析仪看CRC错误计数。如果这个数字一直在涨,说明物理层有问题——可能是线缆太长、终端电阻不对、或者干扰太大。
3.3.6 ACK(应答场)
ACK很有意思。发送方在ACK槽位发隐性电平,接收方如果正确收到数据,就把这个位拉成显性。这样发送方就知道:嗯,有人收到了。
如果没人应答呢?发送方会重发。但重发次数有限,超过一定次数就会报错。我调试时经常用这个特性:故意不接终端电阻,看发送方会不会报错。
3.3.7 EOF(帧结束)
EOF是7个隐性位。表示这帧数据结束了。总线恢复空闲状态,等待下一帧。
3.4 知识体系总览
下面这张图,把CAN总线的基础知识串起来了。从物理层的差分信号,到帧结构的每个字段,一目了然。
3.5 几个容易踩的坑
最后,我分享几个实战中遇到的坑,你们以后碰到了能少走弯路。
坑1:终端电阻不能省
我曾经帮一个客户排查CAN通信故障。他的车在实验室好好的,一上路就丢帧。查了半天,发现他只在总线一端接了120Ω电阻,另一端没接。高速时信号反射严重,数据就丢了。记住:CAN总线两端各需要一个120Ω终端电阻。
坑2:ID分配要留余地
我见过一个项目,ID从0x100开始分配,用到0x1FF就满了。后来要加新功能,发现没ID可用了。我建议:ID分配时,按功能分组,每组之间留一些空ID。比如动力系统用0x100-0x1FF,车身系统用0x200-0x2FF,中间留点余量。
小技巧:调试CAN总线时,我习惯先看物理层。用万用表量CAN_H和CAN_L之间的电阻:正常应该在60Ω左右(两个120Ω并联)。如果量出来是120Ω,说明只有一个终端电阻;如果是0Ω,说明短路了。这个检查只要10秒钟,能排除80%的物理层问题。
好了,CAN总线的基础就讲到这里。差分信号怎么工作的、帧结构每个字段干什么用的、实际项目中要注意什么,我都说清楚了。下一节我们聊CAN总线仲裁和错误处理,那才是真正有意思的部分。
公众号:蓝海资料掘金营,微信deep3321