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个隐性位)组成,用于接收节点尚未准备好接收下一帧时请求延迟。
二、标准帧与扩展帧格式
标准帧(CAN 2.0A)使用11位标识符,扩展帧(CAN 2.0B)使用29位标识符。两者在仲裁场结构上差异明显,其余字段基本一致。
| 字段 | 标准帧 | 扩展帧 |
|---|---|---|
| 帧起始 SOF | 1位显性 | 1位显性 |
| 标识符 | 11位 | 11位基本ID + 18位扩展ID |
| RTR | 1位 | 1位(替代远程请求) |
| SRR / IDE | IDE=0 | SRR=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位。
五、复盘与硬件设计要点
- 标准帧与扩展帧的仲裁场长度不同,过滤器设计需分别配置掩码与匹配值。
- 位填充错误是常见总线错误之一,硬件需在CRC界定符前停止填充检测。
- 错误帧会破坏当前帧,节点应记录错误计数器(TEC/REC),并在超过阈值时进入被动错误或总线关闭状态。
- 过载帧用于接收缓冲不足,但不应滥用,否则会降低总线有效带宽。
掌握帧结构后,下一步就是把这些字段映射到具体的CAN控制器寄存器与过滤器配置中。只有将协议层的位定义与硬件层的寄存器行为对应起来,才能在调试中快速定位仲裁丢失、位填充错误或CRC错误等异常。