3. CAN FD协议帧格式与S32K3实现映射
CAN FD(Flexible Data-rate)在经典CAN的基础上做了两处关键扩展:一是数据场长度从最多8字节扩展到最多64字节;二是允许在帧内切换数据速率,仲裁段仍用标称速率保证多节点竞争的一致性,数据段则用更高的数据速率缩短传输时间。理解帧格式的每一位落在哪里,是后续配置S32K3 FlexCAN模块寄存器、排查通信异常的基础。
一、标准帧与扩展帧的标识结构
CAN FD沿用经典CAN的两种帧格式。标准帧使用11位标识符(ID),扩展帧使用29位标识符,由11位基本ID(Base ID)和18位扩展ID(Extended ID)拼接而成。标识符之后是控制场,其中包含IDE位(区分标准/扩展)、FDF位(区分经典CAN与CAN FD)、BRS位(位速率切换)、ESI位(错误状态指示)以及4位DLC。数据场之后是CRC场,CAN FD的CRC长度由数据长度决定:数据场不超过16字节时使用17位CRC,超过16字节时使用21位CRC,并额外插入填充位(Stuff Bit)以保证位填充规则。帧尾为ACK场与7位帧结束。
需要特别注意的是,CAN FD取消了经典CAN中的远程帧(RTR),因此不存在“远程请求”这种用法;同时FDF位为隐性时表示FD帧,为显性时表示经典CAN帧,二者可在同一总线上共存,但要求控制器支持混合模式。
二、BRS与ESI位的实际含义
BRS(Bit Rate Switch)位于控制场,为显性时表示本帧数据段不切换速率,为隐性时表示从BRS位之后到CRC界定符之前切换到数据段波特率。也就是说,仲裁段和帧尾仍按标称速率发送,只有数据段(含数据场和CRC场)提速。ESI(Error State Indicator)为隐性表示发送节点处于错误被动状态,为显性表示错误主动状态。ESI不改变帧的收发行为,但为网络诊断提供了节点健康度的直接线索——若某节点长期发送ESI隐性帧,说明其错误计数器已超过128,应检查其物理层或终端匹配。
三、DLC编码与数据长度映射
CAN FD的DLC仍为4位,但编码不再线性对应字节数。0~8对应0~8字节,9~15分别对应12、16、20、24、32、48、64字节。这意味着DLC=9时实际数据场为12字节,DLC=15时为64字节。S32K3的FlexCAN模块在接收时会把DLC解码为实际字节数写入MB(Message Buffer)的length字段,发送时则需按目标长度反查DLC值。若配置的DLC与实际写入数据长度不一致,会出现发送截断或接收长度异常。
四、CRC场与S32K3的对应关系
CAN FD的CRC计算覆盖从SOF到数据场结束的所有位,并包含填充位。S32K3 FlexCAN硬件自动完成CRC生成与校验,软件无需干预。但需注意,当数据长度超过16字节时,CRC为21位,且填充位计数器(Stuff Count)会以3位格雷码形式插入在CRC之前。若接收端CRC校验失败,FlexCAN会将帧丢弃并置位错误中断标志。调试时可通过读取CAN_ESR1中的CRCERR位判断是否为CRC错误。
五、S32K3 FlexCAN寄存器映射要点
S32K3的FlexCAN模块通过消息缓冲区(Message Buffer,MB)结构管理收发。每个MB包含控制状态字段(CS)、标识符字段(ID)和数据字段(DATA)。CS字段中的IDE位对应标准/扩展帧选择,RTR位在FD模式下不再使用,EDL位对应FDF位,BRS位和ESI位分别对应帧中的BRS和ESI。DLC字段为4位,硬件在接收时自动将DLC解码为实际字节数,发送时需按目标长度写入正确的DLC编码。
波特率配置分为标称段和数据段两部分。标称段由CAN_CTRL1中的PRESDIV、PROPSEG、PSEG1、PSEG2决定;数据段由CAN_FDCBT中的FPRESDIV、FPSEG1、FPSEG2决定。以常见的500kbps标称速率、2Mbps数据速率为例,假设S32K3的CAN时钟为40MHz,标称段预分频可设为4,得到10MHz的位时间基准,再通过PROPSEG=2、PSEG1=3、PSEG2=2得到总TQ=8,即500kbps;数据段预分频设为1,得到40MHz基准,FPSEG1=2、FPSEG2=1,总TQ=5,即2Mbps。实际配置时需保证采样点位置合理,通常标称段采样点设在75%~80%,数据段设在70%~75%。
六、实操示例:配置一个FD发送MB
以下示例展示如何为S32K3 FlexCAN0配置一个扩展帧、FD、BRS=1、数据长度16字节的发送MB。假设使用MB0,标称速率500kbps,数据速率2Mbps。
/* 1. 使能CAN FD模式 */
CAN0->MCR |= CAN_MCR_FDEN_MASK;
/* 2. 配置标称段波特率:40MHz / (4*(1+2+3+2)) = 500kbps */
CAN0->CTRL1 = CAN_CTRL1_PRESDIV(3) /* 预分频=4 */
| CAN_CTRL1_PROPSEG(2)
| CAN_CTRL1_PSEG1(3)
| CAN_CTRL1_PSEG2(2);
/* 3. 配置数据段波特率:40MHz / (1*(1+2+1+1)) = 2Mbps */
CAN0->FDCBT = CAN_FDCBT_FPRESDIV(0) /* 预分频=1 */
| CAN_FDCBT_FPSEG1(2)
| CAN_FDCBT_FPSEG2(1);
/* 4. 配置MB0为发送,扩展帧,FD,BRS=1,DLC=16字节 */
CAN0->MB[0].CS = CAN_CS_CODE(0xC) /* 发送MB */
| CAN_CS_EDL_MASK /* FD帧 */
| CAN_CS_BRS_MASK /* 速率切换 */
| CAN_CS_DLC(10); /* DLC=10 对应16字节 */
/* 5. 写入扩展ID和数据 */
CAN0->MB[0].ID = 0x12345678 | CAN_ID_EXT_MASK;
CAN0->MB[0].DATA[0] = 0x11;
CAN0->MB[0].DATA[1] = 0x22;
/* ... 填充至16字节 ... */
/* 6. 触发发送 */
CAN0->MB[0].CS |= CAN_CS_CODE(0xC);
发送后可通过读取CAN_IFLAG1中的对应位判断发送完成。若BRS位配置正确,用示波器观察CAN_H/CAN_L差分信号,可看到仲裁段位宽约2μs(500kbps),数据段位宽约0.5μs(2Mbps),切换点位于BRS位之后。若数据段未提速,应检查CAN_MCR[FDEN]是否置位、CAN_FDCBT参数是否合理、以及MB的EDL和BRS位是否同时置位。
七、常见问题与判断依据
接收端若持续报CRC错误,优先检查数据段采样点是否偏移过大,可适当增大FPSEG1或减小FPSEG2。若接收到的DLC与实际不符,检查发送端DLC编码是否按9~15映射表填写。若ESI位长期为隐性,说明节点错误计数器偏高,应检查终端电阻(通常120Ω)和总线长度。标准帧与扩展帧混用时,注意验收滤波器的IDE位配置,避免误过滤。