2. CAN数据链路层:帧结构与位填充
数据链路层,说白了就是CAN协议最核心的部分。你想想看,物理层只管把0和1发到总线上,但怎么区分哪段是地址、哪段是数据、哪段是校验?这就是数据链路层干的事。
我个人习惯把CAN帧结构比作一个快递包裹——有收件人地址、有内容、有签名确认。今天我们就把它拆开,看看每一部分到底长什么样。
2.1 CAN帧的完整结构
先看一张总览图,把整个帧结构印在脑子里。
这张图把标准数据帧的7个主要字段都标出来了。我刚开始学CAN的时候,就是靠这张图反复对照,才把帧结构记牢的。
2.2 逐字段拆解
2.2.1 SOF(帧起始)
SOF只有1位,必须是显性(逻辑0)。它干的事很简单——告诉总线上所有节点:「我要发数据了,大家准备好!」
总线空闲时是隐性电平(逻辑1)。SOF这一位显性,相当于一个「唤醒信号」。我记得有一次调试,发现某个节点总是不响应,查了半天,原来是它的SOF检测电路有问题,把显性位当成了噪声滤掉了。
2.2.2 仲裁场
这是CAN协议最精彩的部分。仲裁场包含:
- 标识符(ID):标准帧11位,扩展帧29位
- RTR位:远程帧请求位(0=数据帧,1=远程帧)
仲裁的原理很简单:谁ID小,谁优先级高。多个节点同时发送时,通过「线与」机制逐位比较,ID小的节点自动获胜。
扩展帧的仲裁场多了18位扩展ID,结构如下:
| 字段 | 位数 | 说明 |
|---|---|---|
| 基础ID | 11位 | 与标准帧相同 |
| SRR位 | 1位 | 替代远程请求位(隐性) |
| IDE位 | 1位 | 标识符扩展位(1=扩展帧) |
| 扩展ID | 18位 | ID的18~28位 |
| RTR位 | 1位 | 远程帧请求 |
2.2.3 控制场
控制场共6位,结构如下:
- IDE位(1位):标识符扩展位。标准帧=0,扩展帧=1
- r0位(1位):保留位,必须为显性
- DLC(4位):数据长度码,表示数据场有多少字节
DLC的取值范围是0~8,对应数据场0~8字节。注意,DLC=0也是合法的——远程帧就没有数据场。
2.2.4 数据场
数据场长度0~8字节,是帧里唯一承载用户数据的地方。发送什么、怎么解析,完全由上层协议决定。
我个人习惯把数据场的字节分配做成一张表,贴在项目文档里。比如:
| 字节 | 信号 | 范围 | 分辨率 |
|---|---|---|---|
| Byte0 | 车速 | 0~250 km/h | 1 km/h |
| Byte1 | 发动机转速 | 0~8000 rpm | 0.125 rpm |
| Byte2~3 | 油门踏板位置 | 0~100% | 0.1% |
这样设计,解析代码写起来特别清晰,调试也方便。
2.2.5 CRC场
CRC场共16位,包含:
- CRC序列(15位):对SOF、仲裁场、控制场、数据场进行CRC计算
- CRC定界符(1位):隐性位,用于分隔
CRC的生成多项式是:x¹⁵ + x¹⁴ + x¹⁰ + x⁸ + x⁷ + x⁴ + x³ + 1。你不需要背这个多项式,但要知道它的检错能力——能检测出所有≤5位的突发错误,以及99.998%的其他错误。
2.2.6 ACK场
ACK场只有2位:
- ACK槽(1位):发送节点发隐性位,接收节点如果正确收到,就拉成显性
- ACK定界符(1位):隐性位
这个机制很有意思。发送节点发出ACK槽位后,会监听总线。如果总线上是显性,说明至少有一个节点正确收到了;如果还是隐性,说明没人收到——发送节点会重发。
你想想看,这相当于一个「集体确认」机制。不需要每个节点单独回复ACK,效率很高。
2.2.7 EOF(帧结束)
EOF共7位,全部为隐性位。它的作用是让总线恢复隐性状态,为下一帧做准备。
EOF之后,总线进入间歇场(ITM,3位隐性),然后才是总线空闲。这个间歇场是协议规定的「冷却时间」,防止连续帧之间产生干扰。
2.3 位填充机制
位填充是CAN协议里一个容易被忽视、但极其重要的机制。它的规则很简单:
为什么要这么做?两个原因:
- 保证时钟同步:CAN总线没有单独的时钟线,节点靠电平跳变来同步时钟。如果长时间没有跳变,时钟就会漂移。
- 防止误判:连续的隐性位可能被误认为总线空闲。
举个例子:假设数据场里有连续6个1(隐性位),发送时会在第5个1后面插入1个0(显性位)。接收方看到5个1后,知道第6位是填充位,直接丢弃。
位填充覆盖的范围是:从SOF到CRC场结束(包括CRC定界符)。ACK场和EOF不参与位填充。
这意味着,一个标准数据帧的实际位数不是固定的。如果数据场全是0x00(8个0),位填充会频繁插入1;如果数据场全是0xFF(8个1),也会频繁插入0。最坏情况下,帧长度会增加约20%。
2.4 帧类型小结
CAN协议定义了4种帧类型,我们这章重点讲的是数据帧。其他三种简单提一下:
| 帧类型 | 用途 | 有无数据场 |
|---|---|---|
| 数据帧 | 发送数据 | 有(0~8字节) |
| 远程帧 | 请求数据 | 无 |
| 错误帧 | 报告总线错误 | 无 |
| 过载帧 | 请求延迟发送 | 无 |
远程帧的帧结构与数据帧几乎一样,区别在于RTR位=1,且没有数据场。错误帧和过载帧我们后面章节再细讲。
2.5 本章要点回顾
- CAN标准数据帧由SOF、仲裁场、控制场、数据场、CRC场、ACK场、EOF共7个字段组成
- 仲裁场通过ID逐位仲裁,ID越小优先级越高
- 数据场最多8字节,DLC必须与实际数据长度一致
- CRC场提供强大的检错能力,覆盖SOF到数据场
- ACK场实现集体确认,不需要单独回复
- 位填充保证时钟同步,每5个相同电平后插入1个相反电平
嗯,帧结构这块内容比较多,但它是CAN协议的基础。你把这些字段的位宽、作用、顺序记清楚,后面学CAN的收发器、控制器、应用层协议都会轻松很多。