3. CAN帧结构详解

CAN总线上的所有通信都以“帧”为基本单位。理解帧结构,是硬件设计与驱动开发的分水岭:只有清楚每一段字段的位宽、位置与作用,才能在示波器或CAN分析仪上准确判断节点行为,也才能写出正确的过滤器配置与中断处理逻辑。本节从帧类型、标准帧与扩展帧格式、位填充与CRC校验三个层面展开。

一、四种帧类型及其组成

CAN 2.0B协议定义了四种帧类型,它们共享相同的位填充与CRC机制,但用途和字段构成不同。

  • 数据帧(Data Frame):携带0~8字节有效数据,是总线上最常见的帧。由帧起始、仲裁场、控制场、数据场、CRC场、应答场、帧结束组成。
  • 远程帧(Remote Frame):由接收节点发出,用于请求具有相同标识符的数据帧。它与数据帧结构几乎一致,区别在于RTR位为隐性(1),且不包含数据场,DLC仍表示期望返回的数据长度。
  • 错误帧(Error Frame):任何节点检测到错误时立即发送,由错误标志(主动错误6个显性位,被动错误6个隐性位)加错误界定符(8个隐性位)构成,用于强制打断当前传输并通知全网。
  • 过载帧(Overload Frame):结构与错误帧类似,由过载标志(6个显性位)和过载界定符(8个隐性位)组成,用于接收节点尚未准备好接收下一帧时请求延迟。
远程帧虽然不携带数据,但DLC字段依然有效。若某节点用远程帧请求数据,发送方需以相同ID的数据帧应答,否则请求方会持续等待。

二、标准帧与扩展帧格式

标准帧(CAN 2.0A)使用11位标识符,扩展帧(CAN 2.0B)使用29位标识符。两者在仲裁场结构上差异明显,其余字段基本一致。

字段 标准帧 扩展帧
帧起始 SOF1位显性1位显性
标识符11位11位基本ID + 18位扩展ID
RTR1位1位(替代远程请求)
SRR / IDEIDE=0SRR=1,IDE=1
控制场IDE + r0 + DLC(4位)IDE + r1 + r0 + DLC(4位)
数据场0~8字节0~8字节
CRC场15位CRC + 1位界定符15位CRC + 1位界定符
应答场ACK槽 + ACK界定符ACK槽 + ACK界定符
帧结束7位隐性7位隐性

扩展帧在基本ID之后插入SRR位(隐性)和IDE位(隐性),再发送18位扩展ID,最后才是RTR位。这种设计保证了标准帧与扩展帧在同一总线上可以共存,且标准帧优先级天然高于扩展帧——因为标准帧的IDE位为显性,在仲裁中会胜出。

三、位填充与CRC校验

CAN采用不归零(NRZ)编码,没有独立的时钟线,因此需要位填充来保证接收端能够从数据流中恢复时钟。规则是:从帧起始到CRC序列结束,发送器每检测到连续5个相同极性位,就自动插入1个相反极性的位。接收端则执行相反操作,将填充位剔除。

位填充的作用有两个:一是保证信号跳变足够频繁,便于接收端同步;二是让错误帧能够可靠地打断总线。需要注意的是,CRC界定符、ACK场和帧结束不参与位填充,这是硬件解码时必须严格区分的边界。

CRC校验采用15位CRC多项式:X^15 + X^14 + X^10 + X^8 + X^7 + X^4 + X^3 + 1。发送器对SOF、仲裁场、控制场、数据场进行CRC计算,将结果附在CRC序列中;接收器用相同多项式重新计算并比对。若不一致,接收器在ACK界定符之后发出错误帧。

// 典型CAN控制器中CRC与位填充相关的寄存器配置片段
CAN->MCR  |= CAN_MCR_CCE;        // 进入配置模式
CAN->BTR  = 0x001C0003;          // 位定时:BRP、TSEG1、TSEG2、SJW
CAN->MCR  &= ~CAN_MCR_CCE;       // 退出配置模式
// 位填充与CRC由硬件自动完成,软件只需关注过滤器与中断
CAN->IER  |= CAN_IER_EPVIE | CAN_IER_BOFIE; // 错误被动与总线关闭中断

四、案例:用分析仪定位“远程帧无应答”故障

某车身控制节点周期性发送远程帧请求电机温度,但始终收不到数据帧。用CAN分析仪抓取总线波形后发现:远程帧的DLC=8,但总线上没有任何节点以相同ID回复。进一步检查发现,电机控制器节点的验收过滤器只配置了数据帧,未使能远程帧接收。修正过滤器配置后,远程帧得到正确应答。

这个案例说明:远程帧的请求与应答依赖标识符匹配和过滤器配置,而不是自动机制。驱动开发中必须显式处理RTR位。

常见误区:认为远程帧可以携带数据。实际上远程帧的数据场长度为0,DLC仅表示期望的数据长度。若发送方用数据帧应答,DLC应与请求一致,否则部分节点会判定为格式错误。

五、复盘与硬件设计要点

  • 标准帧与扩展帧的仲裁场长度不同,过滤器设计需分别配置掩码与匹配值。
  • 位填充错误是常见总线错误之一,硬件需在CRC界定符前停止填充检测。
  • 错误帧会破坏当前帧,节点应记录错误计数器(TEC/REC),并在超过阈值时进入被动错误或总线关闭状态。
  • 过载帧用于接收缓冲不足,但不应滥用,否则会降低总线有效带宽。
CAN标准帧与扩展帧结构对比 · 位填充与CRC校验 标准帧(11位ID) SOF 11位标识符 RTR IDE r0+DLC 数据场 0~8B CRC 15位 ACK EOF 扩展帧(29位ID) SOF 11位基本ID SRR IDE 18位扩展ID RTR r1+r0+DLC 数据场 0~8B CRC 15位 ACK EOF 位填充规则:连续5个相同极性位后插入1个相反位 1 1 1 1 1 0 1 1 ← 填充位 CRC校验流程 发送端计算CRC 附加15位CRC序列 接收端重新计算 比对不一致→错误帧 位填充与CRC由CAN控制器硬件自动完成,软件重点配置过滤器、中断与错误计数器

掌握帧结构后,下一步就是把这些字段映射到具体的CAN控制器寄存器与过滤器配置中。只有将协议层的位定义与硬件层的寄存器行为对应起来,才能在调试中快速定位仲裁丢失、位填充错误或CRC错误等异常。