3、车载网络通信协议(上):CAN总线详解——物理层、数据链路层、报文格式、仲裁机制、错误处理
CAN总线,全称Controller Area Network。说实话,这玩意儿在汽车电子里太重要了。我入行那会儿,第一件事就是啃CAN协议。你想想看,一辆车上几十个ECU,要是没有个靠谱的通信方式,那不乱套了?
CAN总线是德国Bosch公司在80年代搞出来的。初衷很简单——让车上各个电子模块能高效、可靠地交换数据。到今天,它依然是车载网络的中流砥柱。
3.1 物理层:差分信号与总线电平
CAN的物理层,说白了就是两根线——CAN_H和CAN_L。它用差分信号传输,抗干扰能力很强。
为什么用差分?我举个例子。你在车里,发动机点火、空调压缩机启动,电磁干扰到处都是。单端信号很容易被干扰,但差分信号不一样——两根线受到的干扰基本一样,接收端一相减,干扰就抵消了。
| 信号状态 | CAN_H电压 | CAN_L电压 | 差分电压 |
|---|---|---|---|
| 显性(Dominant) | 3.5V | 1.5V | 2.0V |
| 隐性(Recessive) | 2.5V | 2.5V | 0V |
显性电平代表逻辑0,隐性电平代表逻辑1。这里有个关键点——显性电平会覆盖隐性电平。这个特性,就是后面仲裁机制的基础。
3.2 数据链路层:帧结构与位填充
CAN的数据链路层,核心就是帧结构。标准CAN(CAN 2.0A)的帧ID是11位,扩展CAN(CAN 2.0B)是29位。我个人习惯,只要不是老平台,都用扩展帧——兼容性更好。
先看标准数据帧的结构:
SOF + 11位ID + RTR + IDE + r0 + DLC + 数据段(0-8字节) + CRC + ACK + EOF
每个字段都有它的作用。SOF(Start of Frame)是帧起始,一个显性位。ID段决定了消息的优先级。DLC(Data Length Code)告诉接收方数据有多少字节。
嗯,这里要注意位填充(Bit Stuffing)。CAN协议规定,连续发送5个相同电平后,必须插入一个相反电平。为什么?为了保证接收方能从信号边沿提取时钟。我见过有工程师写CAN驱动时忘了处理位填充,结果高速通信时老是同步失败。
3.3 报文格式:标准帧 vs 扩展帧
标准帧和扩展帧的区别,主要在ID长度和格式控制位上。
| 对比项 | 标准帧(CAN 2.0A) | 扩展帧(CAN 2.0B) |
|---|---|---|
| ID长度 | 11位 | 29位 |
| 最大节点数 | 2048 | 5.36亿 |
| IDE位 | 显性(0) | 隐性(1) |
| 数据长度 | 0-8字节 | 0-8字节 |
你可能会问,什么时候用标准帧,什么时候用扩展帧?我的建议是:如果网络简单,节点少,标准帧够用。但现在的车,动辄几十个ECU,还是用扩展帧吧,ID分配起来灵活得多。
3.4 仲裁机制:非破坏性逐位仲裁
CAN的仲裁机制,是我觉得最巧妙的设计之一。多个节点同时发送时,谁优先级高谁先发,而且不会破坏高优先级帧的数据。
原理很简单:总线是线与逻辑。显性位(0)会覆盖隐性位(1)。每个节点在发送ID位时,同时监听总线电平。如果自己发的是隐性位,但总线上是显性位,说明有更高优先级的节点在发,自己就乖乖退出发送。
举个例子:
- 节点A:ID = 0x100(二进制:001 0000 0000)
- 节点B:ID = 0x200(二进制:010 0000 0000)
从最高位开始比较。第1位都是0,没问题。第2位,A发0(显性),B发1(隐性)。总线被A拉成显性,B检测到总线电平与自己发送的不一致,立刻退出。A继续发送,不受影响。
3.5 错误处理:5种错误类型与状态机
CAN的错误处理机制,说实话,挺复杂的。但搞懂了,你就知道为什么CAN这么可靠。
CAN定义了5种错误类型:
- 位错误(Bit Error):发送节点发送的电平与总线电平不一致。
- 填充错误(Stuff Error):连续6个相同电平,违反位填充规则。
- CRC错误:接收方计算的CRC与发送方不一致。
- 形式错误(Form Error):帧格式中固定位段出现非法电平。
- 应答错误(ACK Error):发送方没有收到ACK应答。
每个节点内部有两个计数器:发送错误计数器(TEC)和接收错误计数器(REC)。根据计数值,节点处于三种状态之一:
| 状态 | 条件 | 行为 |
|---|---|---|
| 主动错误(Error Active) | TEC < 128 且 REC < 128 | 发送主动错误标志(6个显性位) |
| 被动错误(Error Passive) | TEC > 127 或 REC > 127 | 发送被动错误标志(6个隐性位) |
| 总线关闭(Bus Off) | TEC > 255 | 完全断开总线,不参与任何通信 |
3.6 CAN知识体系总览
下面这张图,是我自己梳理的CAN知识体系。你可以把它当作学习地图。
这张图把CAN的知识点串起来了。从物理层的差分信号,到数据链路层的帧结构,再到应用层的仲裁机制,最后是错误处理的状态机。你顺着这个脉络学,不会乱。