4、CAN总线帧结构(上):数据帧的标准格式(CAN 2.0A)、ID(标识符)的作用、仲裁场、控制场、数据场

各位同学,今天我们正式进入CAN总线最核心的部分——帧结构。

说实话,搞懂帧结构,你就掌握了CAN通信的“语法”。就像学英语得先懂主谓宾,学CAN就得先搞清楚这帧数据是怎么组织的。我个人习惯把CAN数据帧比作一个“快递包裹”,每一段都有它的使命。

咱们这节课先讲标准格式,也就是CAN 2.0A。它定义了11位ID,是应用最广的基础格式。后面我们会单独讲扩展格式(CAN 2.0B),那个是29位ID,但基础逻辑是一样的。

4.1 数据帧的整体结构

一个标准数据帧,从开始到结束,总共包含7个场。我列个表,大家先有个整体印象:

场名称 位数 作用
帧起始(SOF) 1 bit 同步信号,标志一帧的开始
仲裁场 12 bits 包含ID和RTR位,决定总线访问优先级
控制场 6 bits 包含IDE、保留位、DLC(数据长度码)
数据场 0~64 bits 实际要传输的数据
CRC场 16 bits 校验数据完整性
ACK场 2 bits 接收节点应答确认
帧结束(EOF) 7 bits 标志帧结束

今天咱们重点讲前四个场:帧起始、仲裁场、控制场、数据场。CRC和ACK我们留到下节课细说。

核心要点:标准数据帧总位数 = 1 + 12 + 6 + 0~64 + 16 + 2 + 7 = 44~108 bits。加上3 bits的帧间隔,实际一帧最少47 bits。

4.2 帧起始(SOF)—— 同步的“发令枪”

SOF只有1个bit,固定为显性电平(逻辑0)。

为什么是显性?因为总线空闲时是隐性电平(逻辑1)。SOF从隐性跳变到显性,所有节点都能检测到这个下降沿,从而同步自己的时钟。说白了,这就是一个“大家注意,我要开始发了”的信号。

我在项目中遇到过一个问题:某个节点在总线繁忙时发送SOF,结果因为时钟偏差,SOF的下降沿被其他节点误判为毛刺。后来排查发现是晶振精度不够。嗯,这里要注意,CAN对时钟容差有要求,标准帧要求不超过1.58%。

4.3 仲裁场——ID(标识符)与RTR位

仲裁场是CAN总线最精妙的设计之一。它包含两部分:

  • ID(标识符):11 bits,范围0x000~0x7FF(0~2047)。
  • RTR位:1 bit,Remote Transmission Request,远程帧请求位。

4.3.1 ID的作用:不仅仅是“名字”

很多初学者以为ID就是地址,像I2C那样。其实不是。

CAN的ID有两个核心作用:

  1. 标识消息内容:比如0x123代表“发动机转速”,0x456代表“车速”。接收节点通过ID过滤器只接收自己关心的ID。
  2. 决定总线优先级:ID值越小,优先级越高。0x000是最高优先级,0x7FF是最低。

为什么会这样?因为仲裁机制是“线与”逻辑。显性电平(0)会覆盖隐性电平(1)。多个节点同时发送时,从ID的最高位开始逐位比较,谁先发出隐性(1)而别人发出显性(0),谁就退出竞争。

避坑指南:我曾经在一个项目中,把两个关键信号分别分配了ID=0x100和ID=0x200。结果发现0x100的信号总是优先发送,导致0x200的信号偶尔被延迟。后来我把优先级需求高的信号分配了更小的ID。记住:ID分配要按实时性需求来排,不是随便给的。

4.3.2 RTR位——数据帧 vs 远程帧

RTR位在数据帧中固定为显性(0),在远程帧中为隐性(1)。

远程帧的作用是:一个节点请求另一个节点发送数据。比如ECU_A发送一个远程帧,ID=0x123,RTR=1,意思是“谁有ID=0x123的数据,请发给我”。

仲裁时,如果数据帧和远程帧的ID相同,数据帧优先级更高(因为RTR=0覆盖RTR=1)。

4.4 控制场——IDE、保留位、DLC

控制场共6 bits,结构如下:

位序 名称 说明
bit 0 IDE Identifier Extension,标准帧固定为显性(0)
bit 1 r0 保留位,固定为显性(0)
bit 2~5 DLC Data Length Code,数据长度码,0~8

IDE位:区分标准帧和扩展帧的关键。标准帧IDE=0,扩展帧IDE=1。控制场之后,标准帧直接进入数据场,而扩展帧会插入18位扩展ID。

保留位r0:为了兼容未来扩展,目前固定为0。有些老协议里还有r1,现在统一为r0。

DLC(数据长度码):4 bits,表示数据场有多少个字节。取值范围0~8。注意:DLC=0表示没有数据场,但帧结构依然完整。

重要提醒:DLC虽然可以表示0~15,但CAN协议规定数据场最多8字节。DLC值9~15是无效的,实际传输时数据场长度仍按8字节处理。我曾经见过一个供应商的代码,DLC写成了10,结果接收方解析数据时越界了。所以,DLC一定要控制在0~8之间。

4.5 数据场——真正的“货物”

数据场是帧里唯一承载应用数据的地方。长度0~8字节,由DLC决定。

数据场的排列顺序是MSB优先(大端模式)。比如发送0x12 0x34,先发0x12的高位bit,再发低位bit。

我个人习惯在定义CAN矩阵时,把数据场的字节分配画成表格,这样一目了然:

字节 bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
Byte 0 发动机转速高8位
Byte 1 发动机转速低8位
Byte 2 水温 油压
Byte 3 车速
Byte 4~7 未使用(填充0)

你想想看,如果DLC=4,那Byte 4~7虽然没数据,但接收方还是会读到4个字节的0。所以DLC要精确匹配实际数据长度,别浪费带宽。

4.6 标准帧结构总览(SVG图)

下面这张图把标准数据帧的完整结构画出来了。我建议你把它存下来,调试的时候对照着看。

CAN标准数据帧结构图(CAN 2.0A) CAN标准数据帧结构(CAN 2.0A) SOF 1 bit 仲裁场 12 bits(ID 11 + RTR 1) 控制场 6 bits 数据场 0~64 bits CRC场 16 bits ACK 2 bits EOF 7 bits 间隔 3 bits 各场说明: • SOF:1 bit显性,同步信号 • 仲裁场:11位ID + 1位RTR,决定优先级 • 控制场:IDE + r0 + DLC(4位),描述数据长度 • 数据场:0~8字节,实际数据 • CRC场:15位CRC + 1位CRC分隔符 • ACK场:1位ACK Slot + 1位ACK分隔符 • EOF:7位隐性,帧结束标志

4.7 标准格式 vs 扩展格式(快速对比)

虽然这节课讲标准格式,但我还是想提前做个对比,方便你理解两者的区别:

特性 标准格式(CAN 2.0A) 扩展格式(CAN 2.0B)
ID长度 11 bits 29 bits
IDE位 显性(0) 隐性(1)
仲裁场长度 12 bits 32 bits
最大ID数量 2048 536,870,912
兼容性 所有CAN控制器都支持 需要支持CAN 2.0B的控制器

我个人建议:如果项目对ID数量要求不高(比如少于100个),优先用标准格式。因为标准帧更短,总线利用率更高。只有在需要大量ID分配时,才考虑扩展格式。

实战经验:我在做车载网关项目时,遇到过标准帧和扩展帧混用的情况。有些老节点只支持标准帧,新节点用扩展帧。这时候网关要做ID转换,把扩展帧映射到标准帧的ID范围。嗯,这里要注意,映射时要避免ID冲突,否则仲裁会出问题。

4.8 小结

今天的内容就到这里。我们讲了标准数据帧的四个场:

  • 帧起始(SOF):1 bit显性,同步信号。
  • 仲裁场:11位ID + 1位RTR,ID越小优先级越高。
  • 控制场:IDE + r0 + DLC,DLC决定数据长度。
  • 数据场:0~8字节,大端模式传输。

记住:ID是CAN总线的灵魂。分配ID时,优先级高的信号用小的ID。DLC要精确,别浪费带宽。下节课我们讲CRC和ACK,看看CAN是怎么保证数据不出错的。