资讯详情 CAN 技术系列 04 · CAN 帧格式
📅 2026/11/6 6:33:42
CAN总线技术系列 · 持续更新中本系列从差分电气层一路打到 Linux SocketCAN,把两根线背后的电气/协议/控制器/驱动/实战全拧成一根线。 想系统追更戳这里查看完整专栏【CAN 技术系列】 其他技术系列专栏欢迎关注、交流、共同成长【SPI 技术系列】 【I2C 技术系列】 【串口技术系列】【RISC-V 架构系列】【Linux内核系列】 【操作系统设计思想系列】 【 Android 系统全景专栏】本篇定位:CAN 物理层和位定时讲完,本篇讲协议层——帧格式。CAN 有四种帧:数据帧、远程帧、错误帧、过载帧。数据帧是主战场(SOFID控制数据CRCACKEOF)。本篇逐位讲清帧结构、标准/扩展帧、CAN FD 帧扩展。读完你能看懂任何 CAN 抓包波形,知道每一位什么作用。CAN 帧是协议层的核心I2C 帧(START地址ACK数据STOP)简单。CAN 帧复杂得多——SOF/仲裁/控制/数据/CRC/ACK/EOF 七段,每段有定义,且 CRC15/ACK 机制保证可靠。理解帧格式是抓包分析、错误定位、写驱动的基础。对照 SPI技术系列 04 · SPI 协议与时序详解(CPOL/CPHA) 和 【I2C 技术系列 04】I2C 协议与时序详解 看,理解三种总线帧格式的差异。目录一、四种帧类型二、数据帧结构2.1 经典 CAN 数据帧(标准帧 11bit ID)2.2 各段作用2.3 总位数三、仲裁段(ID RTR IDE)3.1 仲裁段组成3.2 ID(标识符)3.3 RTR(Remote Transmission Request)3.4 IDE(Identifier Extension)3.5 SRR(Substitute Remote Request)四、控制段与数据段4.1 控制段(6 位)4.2 DLC(数据长度码)4.3 数据段五、CRC 段与 ACK 段5.1 CRC 段5.2 CAN FD CRC5.3 ACK 段5.4 ACK 机制意义六、EOF 与帧间隔6.1 EOF(End of Frame)6.2 IFS(Intermission,帧间隔)6.3 挂起传输(Suspend)七、标准帧 vs 扩展帧7.1 ID 长度7.2 帧长度7.3 共存7.4 选择八、CAN FD 帧扩展8.1 FD 帧新增位8.2 FD 帧结构8.3 FD 数据段8.4 FD vs 经典帧识别九、远程帧与错误帧9.1 远程帧(Remote Frame)9.2 远程帧的应用9.3 错误帧(Error Frame)9.4 错误帧作用9.5 过载帧(Overload Frame)十、关键问题 QAQ1:数据帧从 SOF 到 EOF 每一位什么作用?Q2:ACK 位怎么工作?Q3:标准帧和扩展帧能共存吗?Q4:CAN FD 帧和经典帧怎么识别?Q5:远程帧现在还用吗?Q6:CRC15 怎么算?十一、实战案例案例 1:ACK 错误,帧重发案例 2:扩展帧 ID 解析错案例 3:CRC 错,错误帧频发案例 4:CAN FD 数据段被当经典帧解析案例 5:远程帧无响应案例 6:EOF 格式错案例 7:DLC 8 数据截断十二、本篇小结与速查核心要点数据帧速查(标准帧 8 字节)CAN FD 新增位帧类型速查延伸阅读参考资料一、四种帧类型帧类型用途关键特征现代使用状态方向数据帧节点发送实际数据RTR0有数据段0~8 字节CAN FD 可到 64 字节source_group_web_1主用几乎所有业务通信都靠它主用远程帧请求某 ID 的数据RTR1无数据段DLC 需与期望响应长度一致source_group_web_2少用CAN FD 已不支持远程帧source_group_web_3辅助错误帧检测到总线错误时通知所有节点主动错误6 个显性位被动错误6 个隐性位后接 8 个隐性界定符source_group_web_4仍常用是总线健壮性核心机制异常过载帧接收节点来不及处理延迟下一帧6 个显性过载标志 8 个隐性界定符source_group_web_5现代控制器基本不用FIFO 满时通常直接丢帧source_group_web_6流控几个值得注意的点远程帧CAN 标准里没有强制规定收到远程帧后必须自动回复是否响应取决于节点实现4。现代车载/工业系统更常用“周期性发送”或“应用层请求-响应”替代。错误帧触发后当前帧会被破坏所有节点丢弃发送方通常会重传。错误计数器 TEC/REC 决定节点处于主动错误、被动错误还是 Bus Off5。过载帧协议层面允许但现代 OEM 和控制器基本不主动发送FIFO 溢出时更常见的是硬件直接丢帧而不是发过载帧14。严格说 CAN 还有 帧间隔 / Interframe Space不算独立帧类型但用于分隔数据帧和远程帧8。二、数据帧结构2.1 经典 CAN 数据帧(标准帧 11bit ID)┌─────┬──────────┬───────┬──────┬───────┬────────┬──────┬─────┐ │ SOF │ 仲裁段 │ 控制段│数据段│ CRC段 │ ACK段 │ EOF │ IFS │ │ 1位 │ 12位 │ 6位 │0-64位│16位 │ 2位 │ 7位 │ 3位 │ │ │IDRTRIDE│DLC.. │ │CRCDEL│ACKDEL │ │ │ └─────┴──────────┴───────┴──────┴───────┴────────┴──────┴─────┘ 显性 仲裁 控制 数据 校验 应答 结束 间隔2.2 各段作用段位数作用SOF1帧起始(显性),硬同步仲裁段12(标准)/32(扩展)ID RTR IDE,仲裁优先级控制段6IDE/R0 DLC(数据长度)数据段0~64数据(0~8 字节经典,0~64 FD)CRC段16CRC15 CRC界定符(隐性)ACK段2ACK间隙 ACK界定符EOF7帧结束(7 个隐性)IFS3帧间隔(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 位扩展帧不是简单“加长 ID”而是刻意设计成不打坏标准帧节点基础 ID 后面跟 SRR替代 RTR隐性和 IDE隐性。标准帧在这两个位置发显性位所以相同基础 ID 下标准帧一定赢仲裁。只支持标准帧的 2.0A 节点看到扩展帧会当作总线忙而退让不会导致总线锁死。这个设计保证了混合总线上老节点能共存代价就是扩展帧天然低人一等。3.2 ID(标识符)标准帧:11bit ID(0x000~0x7FF)扩展帧:29bit ID(0x00000000~0x1FFFFFFF)ID 决定优先级(ID 越小优先级越高,见 [[05-CAN仲裁与优先级]])扩展帧的价值不在“更多 ID”而在让 ID 自己携带路由和优先级信息从而支持大规模、多供应商、可合并的网络。3.3 RTR(Remote Transmission Request)RTR0:数据帧RTR1:远程帧(请求数据,无数据段)3.4 IDE(Identifier Extension)IDE0:标准帧(11bit ID)IDE1:扩展帧(29bit ID)3.5 SRR(Substitute Remote Request)扩展帧中替代 RTR 位置(固定隐性 1)让标准帧在同基础 ID 下稳定赢过扩展帧保持标准/扩展帧仲裁段长度对齐SRR Substitute Remote Request固定隐性 1。它在扩展帧中占据「标准帧 RTR 的位置」保证同基础 ID 时标准帧优先赢得仲裁同时使扩展帧在该位置表现为「远程请求」隐性不干扰标准帧的远程帧机制。四、控制段与数据段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 字节数000111………8889(无效)1210(无效)1611(无效)2012(无效)2413(无效)3214(无效)4815(无效)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 界定符:固定隐性 15.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 界定符:固定隐性 15.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 RTR1) 控制段(DLC) CRC ACK EOFRTR1(数据帧 RTR0)无数据段请求该 ID 的节点发数据DLC 应等于请求帧的数据长度9.2 远程帧的应用节点 A 想要 ID 0x123 的数据,发远程帧(ID0x123, RTR1)节点 B(提供 0x123 数据)收到,响应数据帧(ID0x123, RTR0, 数据)现代少用(多用应用层请求-响应)9.3 错误帧(Error Frame)错误标志(6位) 错误定界符(8位隐性)主动错误标志:6 个连续显性(主动错误节点发)被动错误标志:6 个连续隐性(被动错误节点发,可能被覆盖)错误定界符:8 个隐性9.4 错误帧作用检测到错误的节点发错误帧破坏当前帧(让所有节点丢弃)发送方重发(自动)9.5 过载帧(Overload Frame)过载标志(6位显性) 过载定界符(7位隐性)接收节点来不及处理,请求延迟下一帧现代控制器 FIFO 深少用十、关键问题 QAQ1:数据帧从 SOF 到 EOF 每一位什么作用?A:SOF(1):帧起始显性,硬同步仲裁段(IDRTRIDE):优先级 帧类型控制段(DLC):数据长度数据段:内容CRC15CRC界定符:校验ACKACK界定符:应答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 位,IDE1 用 29bit ID 解析。案例 3:CRC 错,错误帧频发现象:CAN 总线错误帧频发,通信失败。分析:某节点位定时错(采样点不一致),采错数据,CRC 不符,发错误帧。解决:统一所有节点位定时(采样点 87.5%),CRC 错消失。案例 4:CAN FD 数据段被当经典帧解析现象:CAN FD 帧,抓包工具把数据段按 1M 解析,数据乱。分析:抓包工具不支持 FD,按经典帧速率解析数据段(实际 5M)。解决:用支持 FD 的抓包工具(PCAN-View/CANalyzer),正确识别 BRS 切速。案例 5:远程帧无响应现象:发远程帧(ID0x123, RTR1),无数据帧响应。分析:① 没有节点提供 0x123 数据;② 提供节点没配远程响应;③ DLC 不匹配。解决:确认提供节点存在且配响应,或改用应用层请求(UDS 0x22)。案例 6:EOF 格式错现象:帧末偶发格式错误,重发。分析:EOF 7 个隐性中混入显性(EMI 干扰),格式错。解决:查 EMI 源,加共模扼流圈 TVS,提高抗扰。案例 7:DLC 8 数据截断现象:经典 CAN 发 DLC12,接收只到 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远程帧:RTR1 无数据,少用;错误帧:6 显性8 隐性,破坏当前帧数据帧速查(标准帧 8 字节)段位数内容SOF1显性ID11标识符(优先级)RTR10数据,1远程IDE10标准,1扩展r01保留DLC4数据长度数据0~64数据CRC15校验CRC DEL1隐性ACK1显性(接收方)ACK DEL1隐性EOF7隐性IFS3隐性CAN FD 新增位位含义EDLFD 帧标识(替代经典 r0)BRS切速(1数据段高速)ESI错误状态(1被动错误)帧类型速查帧RTRIDE数据用途标准数据000~8B主用标准远程10无请求扩展数据010~8BJ1939扩展远程11无请求FD 数据0EDL10~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.0Bosch CAN FD SpecificationISO 11898-1(数据链路层)CiA CAN BasicsCAN 技术系列 00 · 总目录 · 上一篇:[[03-CAN位定时与同步]] ·下一篇:[[05-CAN仲裁与优先级]]✨ 感谢你的阅读 ✨技术之路漫漫分享是为了更好地交流。如果本文的内容对你有启发希望能得到你的支持 点赞|⭐ 收藏| 关注如果你在调试过程中遇到了其他问题欢迎在评论区 留言我们一起探讨。关注我一起交流底层开发的那些事儿