3. CAN报文帧结构:数据帧、远程帧、错误帧、过载帧、帧间隔的详细解析

CAN总线上的所有通信行为都通过五种标准帧类型完成。理解每种帧的精确结构、仲裁机制和位填充规则,是诊断通信故障、设计高可靠工业节点的前提。本节逐一拆解五种帧的构成,并重点对比标准帧与扩展帧的差异。

3.1 帧类型概览与仲裁场

CAN 2.0B 规范定义了五种帧,其核心区别在于标识符长度和帧用途。下表列出各帧的基本功能与优先级(数值越小优先级越高)。

帧类型功能标识符长度优先级(隐性位越多优先级越低)
数据帧发送节点向总线传输数据11位(标准)或29位(扩展)由ID决定
远程帧请求其他节点发送指定ID的数据帧11位或29位与同ID数据帧相同
错误帧检测到总线错误时主动通知所有节点无最高(立即打断)
过载帧接收节点请求延迟下一数据帧/远程帧无次高
帧间隔帧间分隔,总线空闲标志无最低(仅当总线空闲时出现)
关键点:远程帧与数据帧使用相同的标识符进行仲裁,但远程帧的RTR位为隐性(1),数据帧的RTR位为显性(0),因此数据帧优先级更高。扩展帧的SRR位替代了标准帧的RTR位位置,且必须为隐性,以保证扩展帧在标准帧之后仲裁。

3.2 数据帧(Data Frame)

数据帧是CAN总线最常用的帧类型,负责将最多8字节数据从发送节点传输到所有接收节点。其结构分为七个场:帧起始、仲裁场、控制场、数据场、CRC场、ACK场、帧结束。

3.2.1 标准数据帧(11位ID)

标准数据帧的位序列如下(SOF为显性位“0”,EOF为7个隐性位“1”):

SOF | 11位标识符 | RTR | IDE | r0 | DLC(4位) | 数据(0~8字节) | CRC(15位) | CRC分隔符 | ACK槽 | ACK分隔符 | EOF(7位)
  • SOF(1位):显性“0”,同步所有节点。
  • 仲裁场(12位):11位标识符 + RTR位(数据帧RTR=0)。
  • 控制场(6位):IDE位(标准帧IDE=0)+ r0保留位 + 4位DLC(数据长度码,0~8)。
  • 数据场(0~64位):MSB优先发送。
  • CRC场(16位):15位CRC + 1位隐性CRC分隔符。
  • ACK场(2位):发送节点输出隐性“1”,接收节点在ACK槽写入显性“0”确认。
  • EOF(7位):全部为隐性“1”。

3.2.2 扩展数据帧(29位ID)

扩展帧在仲裁场和控制场做了调整,以容纳更长的标识符:

SOF | 11位基本ID | SRR | IDE | 18位扩展ID | RTR | r1 | r0 | DLC(4位) | 数据 | CRC | CRC分隔符 | ACK槽 | ACK分隔符 | EOF
  • SRR(1位):替代远程请求位,必须为隐性“1”。
  • IDE(1位):扩展帧IDE=1,标识后续为18位扩展ID。
  • 控制场(6位):r1 + r0两个保留位 + 4位DLC。
工程提示:在XMC系列微控制器(如XMC4500、XMC4800)的CAN模块(MultiCAN+)中,配置帧对象时需明确设置CAN_MO_MOCTR->IDE位。若误将扩展帧配置为标准帧,会导致仲裁失败和总线错误计数增加。

3.3 远程帧(Remote Frame)

远程帧用于请求数据,其结构与数据帧几乎相同,但有两个关键区别:

  • RTR位为隐性“1”(数据帧为显性“0”)。
  • 无数据场,DLC字段指示请求的数据长度,但实际不发送数据字节。

远程帧的仲裁规则:若总线上同时出现相同ID的数据帧和远程帧,数据帧因RTR=0而赢得仲裁。这意味着远程帧无法抢占同ID的数据帧,设计者需确保数据节点在收到远程帧后及时发送响应。

3.4 错误帧(Error Frame)

错误帧是CAN总线错误处理的核心机制。任何节点检测到总线错误后,立即发送错误帧,强制所有节点丢弃当前报文并重新同步。

3.4.1 错误帧结构

错误帧由两个场组成:

  1. 错误标志(Error Flag):6个连续相同位(显性“0”或隐性“1”)。
  2. 错误分隔符(Error Delimiter):8个隐性位“1”。

根据节点错误状态,错误标志分为两种:

节点状态错误标志类型位模式说明
主动错误主动错误标志6个显性位“000000”强制打断当前报文,所有节点检测到位填充/CRC/格式错误
被动错误被动错误标志6个隐性位“111111”不破坏总线,仅当其他节点发送主动错误标志时才能被识别
故障排查要点:在XMC系列中,通过CAN_MO_MOCTR->RXU0和CAN_MO_MOCTR->RXU1状态位可读取错误计数器。若发送错误计数(TEC)超过127,节点状态从“主动错误”切换为“被动错误”,此时错误帧不再包含显性位,可能导致总线无法及时清除错误报文。这是工业现场“总线锁死”的常见原因之一。

3.5 过载帧(Overload Frame)

过载帧用于接收节点在自身处理能力不足时,请求延迟下一个数据帧或远程帧的发送。其结构与错误帧类似:

  • 过载标志(Overload Flag):6个显性位“000000”。
  • 过载分隔符(Overload Delimiter):8个隐性位“11111111”。

过载帧的触发条件:

  1. 接收节点在帧间隔的第一位(间歇场)检测到显性位。
  2. 接收节点在EOF的最后一位采样到显性位(格式错误)。
  3. 接收节点内部缓冲区满,主动请求延迟。
与错误帧的区别:过载帧不会增加节点的错误计数器,仅作为流控机制。在XMC的MultiCAN+模块中,可通过配置CAN_MO_MOCTR->OVL位使能自动过载帧发送,防止接收溢出。

3.6 帧间隔(Interframe Space)

帧间隔用于分隔数据帧/远程帧与后续帧,确保总线状态清晰。其结构因节点状态而异:

节点状态帧间隔组成位长度
主动错误节点间歇场(3位隐性)+ 总线空闲(任意长度隐性)≥3位
被动错误节点间歇场(3位隐性)+ 暂停场(8位隐性)+ 总线空闲≥11位
  • 间歇场(Intermission):3个隐性位,禁止在间歇场发送数据帧/远程帧。
  • 暂停场(Suspend Transmission):仅被动错误节点在间歇场后额外插入8个隐性位,给主动错误节点优先发送机会。
  • 总线空闲(Bus Idle):任意长度的隐性位,任何节点检测到至少11个连续隐性位后即可开始发送。

3.7 帧结构综合对比SVG

下图以标准数据帧为基准,对比远程帧、错误帧、过载帧和帧间隔的位序列差异:

CAN五种帧结构对比图 CAN五种帧结构对比(标准11位ID) 显性位(0) 隐性位(1) 错误标志 过载标志 数据帧 S 11位ID R I r DLC 数据(0~8B) CRC A EOF(7) 远程帧 S 11位ID R=1 I r DLC 无数据 CRC A EOF(7) 错误帧 错误标志(6) 错误分隔符(8) 过载帧 过载标志(6) 过载分隔符(8) 帧间隔 间歇(3) 暂停(8)* 空闲(≥0) *仅被动错误节点插入 SOF=0 RTR=1

3.8 位填充机制与帧完整性

CAN总线采用位填充(Bit Stuffing)规则来保证时钟同步:在SOF到CRC场之间,若连续出现5个相同位,发送节点自动插入一个相反位。接收节点在解码时自动移除填充位。

  • 填充位插入:每5个相同位后插入1个反相位。
  • 填充位检测:若接收节点在6个连续位中未检测到电平变化,则判定为位填充错误,立即发送错误帧。
  • 例外区域:CRC分隔符、ACK场、EOF、间歇场、错误/过载标志不进行位填充。
XMC调试技巧:在XMC的MultiCAN+模块中,通过CAN_MO_MOCTR->STF状态位可查询位填充错误。若频繁出现填充错误,应检查总线位定时配置(尤其是采样点位置)和总线终端电阻(标准120Ω)。错误的采样点会导致边缘采样偏差,误判连续位。

3.9 帧结构在XMC中的配置示例

以下代码展示如何在XMC4500的MultiCAN+模块中配置一个标准数据帧对象(11位ID,DLC=8,发送模式):

/* XMC4500 MultiCAN+ 标准数据帧配置示例 */
#include <xmc_can.h>

/* 定义CAN节点和报文对象 */
XMC_CAN_t *can_node = XMC_CAN0;
uint8_t mo_number = 1;

/* 配置报文对象为发送数据帧 */
XMC_CAN_MO_t mo_config = {
    .can_mo_ptr = XMC_CAN0_MO1,
    .can_node = can_node,
    .mo_type = XMC_CAN_MO_TYPE_TRANSMSGOBJ,
    .id_mode = XMC_CAN_FRAME_TYPE_STANDARD_11B,
    .id = 0x123,          /* 11位标识符 */
    .dlc = 8,             /* 数据长度8字节 */
    .ide = 0,             /* 标准帧 */
    .rtr = 0              /* 数据帧 */
};

/* 初始化报文对象 */
XMC_CAN_MO_Init(&mo_config);

/* 设置发送数据缓冲区 */
uint8_t tx_data[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
XMC_CAN_MO_UpdateData(&mo_config, tx_data);

/* 请求发送 */
XMC_CAN_MO_Transmit(&mo_config);
常见配置错误:若id_mode误设为XMC_CAN_FRAME_TYPE_EXTENDED_29B但实际发送11位ID,总线上的扩展帧接收节点将无法识别该报文,导致ACK缺失和发送错误计数上升。务必在初始化前确认IDE位与标识符长度的一致性。

3.10 帧类型与错误状态的关系

错误帧和过载帧的发送时机与节点错误状态密切相关。下表总结不同状态下各帧的发送行为:

节点状态发送数据帧/远程帧发送错误帧发送过载帧帧间隔暂停场
主动错误正常主动错误标志(6显性)正常无
被动错误正常(但发送后需等待8位暂停)被动错误标志(6隐性)正常有(8位隐性)
总线关闭禁止发送禁止发送禁止发送不参与

在XMC系列中,通过读取CAN_NSR->LEC(最后错误代码)寄存器可快速定位错误类型:

  • LEC=1:位填充错误
  • LEC=2:格式错误
  • LEC=3:ACK错误
  • LEC=4:隐性位错误
  • LEC=5:显性位错误
  • LEC=6:CRC错误
  • LEC=7:无错误
工业现场排查建议:当总线出现大量错误帧时,首先使用CAN分析仪捕获原始位流,检查是否存在连续的显性位(超过5个)导致的填充错误。其次,检查XMC的CAN_NSR->TEC和CAN_NSR->REC错误计数器,若TEC快速上升至127以上,说明发送节点存在硬件故障(如驱动器短路或时钟偏差过大)。