CAN 技术系列 04 · CAN 帧格式

📚 CAN总线技术系列 · 持续更新中

本系列从差分电气层一路打到 Linux SocketCAN,把"两根线"背后的电气/协议/控制器/驱动/实战全拧成一根线。

👉 想系统追更,戳这里查看完整专栏:

【CAN 技术系列】

👉 其他技术系列专栏,欢迎关注、交流、共同成长:

【SPI 技术系列】 【I2C 技术系列】 【串口技术系列】【RISC-V 架构系列】【Linux内核系列】 【操作系统设计思想系列】 【 Android 系统全景专栏】


本篇定位:CAN 物理层和位定时讲完,本篇讲协议层------帧格式。CAN 有四种帧:数据帧、远程帧、错误帧、过载帧。数据帧是主战场(SOF+ID+控制+数据+CRC+ACK+EOF)。本篇逐位讲清帧结构、标准/扩展帧、CAN FD 帧扩展。读完你能看懂任何 CAN 抓包波形,知道每一位什么作用。
CAN 帧是协议层的核心

I2C 帧(START+地址+ACK+数据+STOP)简单。CAN 帧复杂得多 ------SOF/仲裁/控制/数据/CRC/ACK/EOF 七段,每段有定义,且 CRC15/ACK 机制保证可靠。理解帧格式是抓包分析、错误定位、写驱动的基础。对照 SPI技术系列 04 · SPI 协议与时序详解(CPOL/CPHA) 和 【I2C 技术系列 04】I2C 协议与时序详解 看,理解三种总线帧格式的差异。


目录

  • 一、四种帧类型
    • [1.1 数据帧(主用)](#1.1 数据帧(主用))
    • [1.2 远程帧](#1.2 远程帧)
    • [1.3 错误帧](#1.3 错误帧)
    • [1.4 过载帧](#1.4 过载帧)
  • 二、数据帧结构
    • [2.1 经典 CAN 数据帧(标准帧 11bit ID)](#2.1 经典 CAN 数据帧(标准帧 11bit ID))
    • [2.2 各段作用](#2.2 各段作用)
    • [2.3 总位数](#2.3 总位数)
  • [三、仲裁段(ID + RTR + IDE)](#三、仲裁段(ID + RTR + IDE))
    • [3.1 仲裁段组成](#3.1 仲裁段组成)
    • [3.2 ID(标识符)](#3.2 ID(标识符))
    • [3.3 RTR(Remote Transmission Request)](#3.3 RTR(Remote Transmission Request))
    • [3.4 IDE(Identifier Extension)](#3.4 IDE(Identifier Extension))
    • [3.5 SRR(Substitute Remote Request)](#3.5 SRR(Substitute Remote Request))
  • 四、控制段与数据段
    • [4.1 控制段(6 位)](#4.1 控制段(6 位))
    • [4.2 DLC(数据长度码)](#4.2 DLC(数据长度码))
    • [4.3 数据段](#4.3 数据段)
  • [五、CRC 段与 ACK 段](#五、CRC 段与 ACK 段)
    • [5.1 CRC 段](#5.1 CRC 段)
    • [5.2 CAN FD CRC](#5.2 CAN FD CRC)
    • [5.3 ACK 段](#5.3 ACK 段)
    • [5.4 ACK 机制意义](#5.4 ACK 机制意义)
  • [六、EOF 与帧间隔](#六、EOF 与帧间隔)
    • [6.1 EOF(End of Frame)](#6.1 EOF(End of Frame))
    • [6.2 IFS(Intermission,帧间隔)](#6.2 IFS(Intermission,帧间隔))
    • [6.3 挂起传输(Suspend)](#6.3 挂起传输(Suspend))
  • [七、标准帧 vs 扩展帧](#七、标准帧 vs 扩展帧)
    • [7.1 ID 长度](#7.1 ID 长度)
    • [7.2 帧长度](#7.2 帧长度)
    • [7.3 共存](#7.3 共存)
    • [7.4 选择](#7.4 选择)
  • [八、CAN FD 帧扩展](#八、CAN FD 帧扩展)
    • [8.1 FD 帧新增位](#8.1 FD 帧新增位)
    • [8.2 FD 帧结构](#8.2 FD 帧结构)
    • [8.3 FD 数据段](#8.3 FD 数据段)
    • [8.4 FD vs 经典帧识别](#8.4 FD vs 经典帧识别)
  • 九、远程帧与错误帧
    • [9.1 远程帧(Remote Frame)](#9.1 远程帧(Remote Frame))
    • [9.2 远程帧的应用](#9.2 远程帧的应用)
    • [9.3 错误帧(Error Frame)](#9.3 错误帧(Error Frame))
    • [9.4 错误帧作用](#9.4 错误帧作用)
    • [9.5 过载帧(Overload Frame)](#9.5 过载帧(Overload Frame))
  • [十、关键问题 Q&A](#十、关键问题 Q&A)
    • [Q1:数据帧从 SOF 到 EOF 每一位什么作用?](#Q1:数据帧从 SOF 到 EOF 每一位什么作用?)
    • [Q2:ACK 位怎么工作?](#Q2:ACK 位怎么工作?)
    • Q3:标准帧和扩展帧能共存吗?
    • [Q4:CAN FD 帧和经典帧怎么识别?](#Q4:CAN FD 帧和经典帧怎么识别?)
    • Q5:远程帧现在还用吗?
    • [Q6:CRC15 怎么算?](#Q6:CRC15 怎么算?)
  • 十一、实战案例
    • [案例 1:ACK 错误,帧重发](#案例 1:ACK 错误,帧重发)
    • [案例 2:扩展帧 ID 解析错](#案例 2:扩展帧 ID 解析错)
    • [案例 3:CRC 错,错误帧频发](#案例 3:CRC 错,错误帧频发)
    • [案例 4:CAN FD 数据段被当经典帧解析](#案例 4:CAN FD 数据段被当经典帧解析)
    • [案例 5:远程帧无响应](#案例 5:远程帧无响应)
    • [案例 6:EOF 格式错](#案例 6:EOF 格式错)
    • [案例 7:DLC > 8 数据截断](#案例 7:DLC > 8 数据截断)
  • 十二、本篇小结与速查
    • 核心要点
    • [数据帧速查(标准帧 8 字节)](#数据帧速查(标准帧 8 字节))
    • [CAN FD 新增位](#CAN FD 新增位)
    • 帧类型速查
  • 延伸阅读
  • 参考资料

一、四种帧类型

帧类型 用途 方向
数据帧(Data Frame) 发送数据 主用
远程帧(Remote Frame) 请求某 ID 数据 辅助
错误帧(Error Frame) 报错 异常
过载帧(Overload Frame) 请求延迟下一帧 流控

1.1 数据帧(主用)

节点发送数据用,最常见。

1.2 远程帧

节点请求某 ID 的数据(被动请求)。RTR=1,无数据段。现代 CAN 少用(多用应用层请求)。

1.3 错误帧

节点检测到错误时发,6 个连续显性(主动错误)或 6 个隐性(被动错误)+ 8 个隐性定界。破坏当前帧,所有节点丢弃。

1.4 过载帧

接收节点来不及处理,请求延迟下一帧。现代控制器 FIFO 深少用。


二、数据帧结构

2.1 经典 CAN 数据帧(标准帧 11bit ID)

复制代码
┌─────┬──────────┬───────┬──────┬───────┬────────┬──────┬─────┐
│ SOF │ 仲裁段   │ 控制段│数据段│ CRC段 │ ACK段  │ EOF  │ IFS │
│ 1位 │ 12位     │ 6位   │0-64位│16位   │ 2位    │ 7位  │ 3位 │
│     │ID+RTR+IDE│DLC+.. │      │CRC+DEL│ACK+DEL │      │     │
└─────┴──────────┴───────┴──────┴───────┴────────┴──────┴─────┘
 显性   仲裁       控制    数据   校验    应答     结束   间隔

2.2 各段作用

段 位数 作用
SOF 1 帧起始(显性),硬同步
仲裁段 12(标准)/32(扩展) ID + RTR + IDE,仲裁优先级
控制段 6 IDE/R0 + DLC(数据长度)
数据段 0~64 数据(0~8 字节经典,0~64 FD)
CRC段 16 CRC15 + CRC界定符(隐性)
ACK段 2 ACK间隙 + ACK界定符
EOF 7 帧结束(7 个隐性)
IFS 3 帧间隔(3 个隐性,下一帧前)

2.3 总位数

  • 标准数据帧(8字节):~111 位(含填充)
  • 扩展数据帧(8字节):~135 位
  • CAN FD(64字节):更长,但数据段高速

三、仲裁段(ID + RTR + IDE)

3.1 仲裁段组成

标准帧(11bit ID):

复制代码
SOF(1) + ID[10:0](11) + RTR(1) + IDE(1) + r0(1) = 15 位

扩展帧(29bit ID):

复制代码
SOF(1) + ID[28:18](11) + SRR(1) + IDE(1) + ID[17:0](18) + RTR(1) + r1(1) + r0(1) = 35 位

3.2 ID(标识符)

  • 标准帧:11bit ID(0x000~0x7FF)
  • 扩展帧:29bit ID(0x00000000~0x1FFFFFFF)
  • ID 决定优先级(ID 越小优先级越高,见 \[05-CAN仲裁与优先级])

3.3 RTR(Remote Transmission Request)

  • RTR=0:数据帧
  • RTR=1:远程帧(请求数据,无数据段)

3.4 IDE(Identifier Extension)

  • IDE=0:标准帧(11bit ID)
  • IDE=1:扩展帧(29bit ID)

3.5 SRR(Substitute Remote Request)

  • 扩展帧中替代 RTR 位置(固定隐性 1)
  • 保持标准/扩展帧仲裁段长度对齐

四、控制段与数据段

4.1 控制段(6 位)

标准帧:

复制代码
IDE(0) + r0 + DLC[3:0] = 6 位

扩展帧:

复制代码
r1 + r0 + DLC[3:0] = 6 位
  • r0/r1:保留位(显性 0)
  • DLC:数据长度码(4bit,0~8)

4.2 DLC(数据长度码)

DLC 经典 CAN 字节数 CAN FD 字节数
0 0 0
1 1 1
... ... ...
8 8 8
9 (无效) 12
10 (无效) 16
11 (无效) 20
12 (无效) 24
13 (无效) 32
14 (无效) 48
15 (无效) 64
  • 经典 CAN:0~8 字节(DLC > 8 视为 8)
  • CAN FD:0~64 字节(DLC 9~15 映射 12/16/20/24/32/48/64)

4.3 数据段

  • 经典:0~8 字节,MSB 先发
  • CAN FD:0~64 字节
  • 内容由应用层定(见 \[07-CAN高层协议])

五、CRC 段与 ACK 段

5.1 CRC 段

复制代码
CRC序列(15bit) + CRC界定符(1位隐性)
  • CRC15:多项式 0x4599,计算 SOF 到数据段
  • 所有节点计算 CRC,和发送方比对
  • 不符 → 发错误帧
  • CRC 界定符:固定隐性 1

5.2 CAN FD CRC

  • 数据 0~16 字节:CRC17(17bit)
  • 数据 20~64 字节:CRC21(21bit)
  • FD CRC 更长(数据多,可靠性要求高)
  • FD 还有 Stuff Count(固定位填充计数)

5.3 ACK 段

复制代码
ACK间隙(1位) + ACK界定符(1位隐性)
  • ACK 间隙:发送方发隐性,所有正确接收的节点发显性(覆盖)
  • 发送方读到显性 = 至少一个节点正确接收
  • 发送方读到隐性 = 无节点正确接收 → ACK 错误
  • ACK 界定符:固定隐性 1

5.4 ACK 机制意义

  • 发送方知道帧被正确接收(显性 ACK)
  • 没收到 ACK = 总线无其他节点 / 所有节点都错 → 重发
  • 这是 CAN 可靠性的关键之一(对比 SPI 无 ACK)

ACK 是 CAN 和 SPI 的重要区别

SPI 无 ACK,从机死机主机不知道。CAN 有 ACK,发送方靠 ACK 位确认至少一个节点正确接收 。无 ACK 自动重发。这是 CAN 汽车级可靠的协议层保障。对照SPI技术系列 04 · SPI 协议与时序详解(CPOL/CPHA) 看,SPI 全双工无 ACK,CAN 半双工有 ACK。


六、EOF 与帧间隔

6.1 EOF(End of Frame)

  • 7 个连续隐性位
  • 标志帧结束
  • 任何显性位(7 个隐性中)→ 格式错误

6.2 IFS(Intermission,帧间隔)

  • 3 个连续隐性位
  • 帧间隔离,下一帧前必须等待
  • IFS 中显性 → 过载帧(请求延迟)

6.3 挂起传输(Suspend)

  • 主动错误节点在 IFS 后可发下一帧
  • 被动错误节点在 IFS 后还要等 8 个隐性(挂起传输),降低优先级

七、标准帧 vs 扩展帧

7.1 ID 长度

  • 标准帧:11bit ID(0x000~0x7FF,2048 个 ID)
  • 扩展帧:29bit ID(5.37 亿个 ID)

7.2 帧长度

  • 标准帧(8字节):~111 位
  • 扩展帧(8字节):~135 位(多 18bit ID + SRR + r1)

7.3 共存

  • 标准帧和扩展帧可共存同一总线
  • 仲裁时:标准帧 11bit ID 和扩展帧高 11bit 比较(IDE 位前)
  • 设计建议:同一总线尽量用一种(避免仲裁歧义)

7.4 选择

  • 标准帧:多数场景够(2048 ID)
  • 扩展帧:J1939(商用车,29bit 编码)/ 大量节点
  • 性能:扩展帧多 24 位开销,效率略低

八、CAN FD 帧扩展

8.1 FD 帧新增位

CAN FD 在控制段新增:

复制代码
控制段(FD): IDE/r1 + r0 + BRS + ESI + DLC[3:0]
  • BRS(Bit Rate Switch):1 = 数据段切高速
  • ESI(Error State Indicator):1 = 节点处于被动错误状态

8.2 FD 帧结构

复制代码
SOF + 仲裁段(1M) + 控制段(含BRS/ESI) ─BRS─> 数据段(5M) + CRC(高速) ─> ACK + EOF(1M)
  • 仲裁段 1M(兼容)
  • BRS 后切 5M/8M(数据段 + CRC)
  • ACK 前回到 1M(全网同步 ACK)

8.3 FD 数据段

  • 0~64 字节(DLC 9~15 映射)
  • 数据段高速(5M/8M)
  • CRC17/21(更长)

8.4 FD vs 经典帧识别

  • 控制段 IDE 位后:经典帧是 r0(显性0),FD 帧是 EDL(隐性1)
  • 控制器自动识别,软件透明

九、远程帧与错误帧

9.1 远程帧(Remote Frame)

复制代码
SOF + 仲裁段(ID + RTR=1) + 控制段(DLC) + CRC + ACK + EOF
  • RTR=1(数据帧 RTR=0)
  • 无数据段
  • 请求该 ID 的节点发数据
  • DLC 应等于请求帧的数据长度

9.2 远程帧的应用

  • 节点 A 想要 ID 0x123 的数据,发远程帧(ID=0x123, RTR=1)
  • 节点 B(提供 0x123 数据)收到,响应数据帧(ID=0x123, RTR=0, 数据)
  • 现代少用(多用应用层请求-响应)

9.3 错误帧(Error Frame)

复制代码
错误标志(6位) + 错误定界符(8位隐性)
  • 主动错误标志:6 个连续显性(主动错误节点发)
  • 被动错误标志:6 个连续隐性(被动错误节点发,可能被覆盖)
  • 错误定界符:8 个隐性

9.4 错误帧作用

  • 检测到错误的节点发错误帧
  • 破坏当前帧(让所有节点丢弃)
  • 发送方重发(自动)

9.5 过载帧(Overload Frame)

复制代码
过载标志(6位显性) + 过载定界符(7位隐性)
  • 接收节点来不及处理,请求延迟下一帧
  • 现代控制器 FIFO 深少用

十、关键问题 Q&A

Q1:数据帧从 SOF 到 EOF 每一位什么作用?

A:

  • SOF(1):帧起始显性,硬同步
  • 仲裁段(ID+RTR+IDE):优先级 + 帧类型
  • 控制段(DLC):数据长度
  • 数据段:内容
  • CRC15+CRC界定符:校验
  • ACK+ACK界定符:应答
  • EOF(7隐性):结束
  • IFS(3隐性):间隔

Q2:ACK 位怎么工作?

A :发送方在 ACK 间隙发隐性,所有正确接收的节点发显性覆盖 (线与)。发送方读到显性 = 至少一个节点正确接收。读到隐性 = 无节点正确接收(ACK 错误,重发)。这是 CAN 可靠性关键------发送方知道帧被接收。

Q3:标准帧和扩展帧能共存吗?

A :能。仲裁时标准帧 11bit ID 和扩展帧高 11bit 比较(IDE 位前),IDE 位决定后续。但建议同一总线用一种,避免仲裁歧义(标准帧 ID 和扩展帧高 11bit 相同时,标准帧优先级高)。

Q4:CAN FD 帧和经典帧怎么识别?

A :控制段 IDE 位后,经典帧是 r0(显性0),FD 帧是 EDL(隐性1)。控制器硬件自动识别,软件透明(配置 FD 模式后,收发自动区分)。

Q5:远程帧现在还用吗?

A :少用。早期 CAN 用远程帧请求数据(节点 A 发远程,节点 B 响应数据)。现代多用应用层请求-响应(如 UDS 0x22 读数据),更灵活。部分老设备(CANopen PDO 请求)还用。

Q6:CRC15 怎么算?

A:多项式 0x4599,计算范围 SOF 到数据段(含填充位)。发送方算 CRC 放 CRC 段,接收方重算比对。不符发错误帧。FD 帧 0~16 字节用 CRC17,20~64 字节用 CRC21(数据多需更强 CRC)。


十一、实战案例

案例 1:ACK 错误,帧重发

现象:某节点发送,示波器看 ACK 间隙是隐性(无应答),帧重发。

分析:总线无其他节点(单节点自测),或所有节点都错(没正确接收)。

解决:单节点自测开 Loopback 模式(自收自发 ACK);多节点检查接收节点是否正常。

案例 2:扩展帧 ID 解析错

现象:29bit ID 抓包,解析成标准帧 ID 错。

分析:抓包工具或代码没识别 IDE 位,把扩展帧当标准帧。

解决:解析时检查 IDE 位,IDE=1 用 29bit ID 解析。

案例 3:CRC 错,错误帧频发

现象:CAN 总线错误帧频发,通信失败。

分析:某节点位定时错(采样点不一致),采错数据,CRC 不符,发错误帧。

解决:统一所有节点位定时(采样点 87.5%),CRC 错消失。

案例 4:CAN FD 数据段被当经典帧解析

现象:CAN FD 帧,抓包工具把数据段按 1M 解析,数据乱。

分析:抓包工具不支持 FD,按经典帧速率解析数据段(实际 5M)。

解决:用支持 FD 的抓包工具(PCAN-View/CANalyzer),正确识别 BRS 切速。

案例 5:远程帧无响应

现象:发远程帧(ID=0x123, RTR=1),无数据帧响应。

分析:① 没有节点提供 0x123 数据;② 提供节点没配远程响应;③ DLC 不匹配。

解决:确认提供节点存在且配响应,或改用应用层请求(UDS 0x22)。

案例 6:EOF 格式错

现象:帧末偶发格式错误,重发。

分析:EOF 7 个隐性中混入显性(EMI 干扰),格式错。

解决:查 EMI 源,加共模扼流圈 + TVS,提高抗扰。

案例 7:DLC > 8 数据截断

现象:经典 CAN 发 DLC=12,接收只到 8 字节。

分析:经典 CAN DLC > 8 视为 8,只发 8 字节。

解决:要发 > 8 字节用 CAN FD,或用 ISO-TP 多帧分包(见 \[07-CAN高层协议])。


十二、本篇小结与速查

核心要点

  • 四种帧:数据帧(主用)/远程帧(请求)/错误帧(报错)/过载帧(流控)
  • 数据帧七段:SOF + 仲裁段 + 控制段 + 数据段 + CRC段 + ACK段 + EOF + IFS
  • 仲裁段:ID(11/29bit) + RTR(0数据/1远程) + IDE(0标准/1扩展)
  • 控制段:DLC(08经典/064 FD)
  • CRC段:CRC15(经典)/CRC17-21(FD) + 界定符
  • ACK段:发送方隐性,接收方显性覆盖(线与),发送方确认被接收
  • EOF:7 隐性;IFS:3 隐性(间隔)
  • 标准帧 11bit ID(2048),扩展帧 29bit ID(J1939 用)
  • CAN FD:BRS 切速 + ESI 错误状态 + 数据段 64 字节 + CRC17/21
  • 远程帧:RTR=1 无数据,少用;错误帧:6 显性+8 隐性,破坏当前帧

数据帧速查(标准帧 8 字节)

段 位数 内容
SOF 1 显性
ID 11 标识符(优先级)
RTR 1 0=数据,1=远程
IDE 1 0=标准,1=扩展
r0 1 保留
DLC 4 数据长度
数据 0~64 数据
CRC 15 校验
CRC DEL 1 隐性
ACK 1 显性(接收方)
ACK DEL 1 隐性
EOF 7 隐性
IFS 3 隐性

CAN FD 新增位

位 含义
EDL FD 帧标识(替代经典 r0)
BRS 切速(1=数据段高速)
ESI 错误状态(1=被动错误)

帧类型速查

帧 RTR IDE 数据 用途
标准数据 0 0 0~8B 主用
标准远程 1 0 无 请求
扩展数据 0 1 0~8B J1939
扩展远程 1 1 无 请求
FD 数据 0 EDL=1 0~64B 高速大块

延伸阅读

  • \[03-CAN位定时与同步] ------ SOF 同步
  • \[05-CAN仲裁与优先级] ------ 仲裁段深入
  • \[06-CAN错误处理与错误帧] ------ 错误帧机制
  • \[07-CAN高层协议] ------ 数据段语义
  • \[08-CAN控制器寄存器与IP架构] ------ 帧寄存器
  • \[04-I2C协议时序与地址] ------ 对比 I2C 帧
  • \[04-SPI协议与时序详解-CPOL-CPHA] ------ 对比 SPI 帧

参考资料

  • Bosch CAN Specification 2.0
  • Bosch CAN FD Specification
  • ISO 11898-1(数据链路层)
  • CiA CAN Basics

CAN 技术系列 00 · 总目录 · 上一篇:\[03-CAN位定时与同步] · 下一篇:\[05-CAN仲裁与优先级]


✨ 感谢你的阅读 ✨

技术之路漫漫,分享是为了更好地交流。

如果本文的内容对你有启发,希望能得到你的支持:

👍 点赞 | ⭐ 收藏 | 👀 关注

如果你在调试过程中遇到了其他问题,

欢迎在 评论区 💬 留言,我们一起探讨。

关注我,一起交流底层开发的那些事儿!🚀


相关推荐
硅基手札20 小时前
操作系统设计思想系列 13 · NuttX 深度 — POSIX 飞控底座 + RTOS 群像
架构·操作系统·嵌入式开发·ecos·sel4·nuttx
万物智能信息科技1 天前
六轴传感器Motion驱动框架开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
驱动开发·华为·开源·harmonyos·鸿蒙
硅基手札1 天前
CAN 技术系列 03 · CAN 位定时与同步
嵌入式开发·通信协议·can总线·bug定位调试
晓蛋2 天前
嵌入式开发中的C语言特性
嵌入式开发·陷阱·编程技巧·缺陷·c语言特性
AMASENSYS艾马斯2 天前
变频器滤波器选型与EMC合规建议
驱动开发·单片机·其他·硬件工程·精益工程
沃普天科技2 天前
100W 氮化镓充电器充电头扩展坞一体化设计,实用性翻倍
驱动开发·计算机外设·音视频·硬件工程·pcb工艺
硅基手札2 天前
操作系统设计思想系列 11 · ThreadX 深度 — 预抢占阈值·认证型设计
操作系统·开源项目·嵌入式开发·嵌入式操作系统·设计思想·threadx
硅基手札3 天前
操作系统设计思想系列 10 · VxWorks 深度 — 硬实时旗舰·完全抢占内核
操作系统·实时操作系统·嵌入式开发·vxworks·设计思想
硅基手札3 天前
Android 系统全景专栏 00 · 总目录
android·操作系统·嵌入式开发