4. CAN数据链路层:帧类型与帧结构

CAN总线数据链路层是协议的核心,它定义了数据如何封装、传输与校验。在变量施肥控制器中,ECU(电子控制单元)之间通过特定格式的帧(Frame)进行通信。本章将深入剖析四种帧类型及其内部结构。

4.1 四种帧类型概述

CAN总线定义了四种不同的帧类型,分别用于数据交换、请求、错误处理和流量控制。在变量施肥系统中,数据帧和远程帧是日常通信的主力,而错误帧和过载帧则保障了网络的健壮性。

帧类型 英文名称 主要用途 在变量施肥中的应用场景
数据帧 Data Frame 发送节点向总线广播数据 GPS模块发送经纬度、排肥器反馈当前转速
远程帧 Remote Frame 请求其他节点发送指定ID的数据 主控制器请求某个执行器的状态参数
错误帧 Error Frame 检测到总线错误时通知所有节点 总线短路或位错误时触发,系统进入故障保护
过载帧 Overload Frame 节点因过载而请求延迟发送 控制器CPU繁忙时,请求总线暂缓新报文
实战提示:在变量施肥控制器固件开发中,99%的通信量来自数据帧。远程帧常用于轮询传感器数据,而错误帧和过载帧通常由CAN控制器硬件自动处理,开发者只需在中断服务函数中读取错误状态寄存器即可。

4.2 数据帧的完整结构

数据帧是CAN通信中最常用的帧类型。它由七个不同的场(Field)组成,每个场都有特定的功能和长度。理解这些场是进行CAN报文解析与封装的基础。

CAN 2.0A 标准数据帧结构(11位ID) SOF 1 bit 仲裁场 ID (11 bit) + RTR (1 bit) 12 bits 控制场 IDE + r0 + DLC 6 bits 数据场 0 ~ 8 字节 0 ~ 64 bits CRC场 15 bit + 1 界定符 16 bits ACK场 2 bits 2 bits EOF 7 bits 7 bits 各场功能说明: • SOF(帧起始):1个显性位,同步所有节点。 • 仲裁场:包含11位标识符(ID)和RTR位,决定总线访问优先级。 • 控制场:包含IDE位、保留位r0和4位数据长度码(DLC)。 • 数据场:0~8字节有效载荷,变量施肥控制指令和传感器数据存放于此。 • CRC场:15位CRC校验 + 1位界定符,确保数据完整性。

4.3 各场深度解析

4.3.1 SOF(帧起始)

SOF由一个显性位(逻辑0)构成。在总线空闲时,任何节点发送SOF即宣告开始占用总线。所有节点的位同步都在SOF的下降沿重新校准。

4.3.2 仲裁场(Arbitration Field)

仲裁场是CAN总线实现非破坏性逐位仲裁的关键。它包含:

  • 标识符(ID):标准帧为11位,扩展帧为29位。ID值越小,优先级越高。在变量施肥系统中,通常将紧急报文(如故障码)分配较小的ID。
  • RTR位(远程发送请求位):数据帧中RTR为显性(0),远程帧中RTR为隐性(1)。这是区分数据帧和远程帧的唯一标志。
仲裁规则:当多个节点同时发送时,总线上的显性位(0)会覆盖隐性位(1)。发送隐性位但检测到显性位的节点会立即退出竞争,转为接收状态。这一过程在硬件层面完成,无需软件干预。

4.3.3 控制场(Control Field)

控制场由6位组成,结构如下:

位序 名称 说明
1 IDE(标识符扩展位) 标准帧为显性(0),扩展帧为隐性(1)
2 r0(保留位) 显性位,未来扩展用
3~6 DLC(数据长度码) 4位二进制,表示数据场字节数(0~8)

4.3.4 数据场(Data Field)

数据场承载实际信息,长度为0~8字节。在变量施肥控制器中,数据场的编码通常遵循自定义的协议或SAE J1939协议。例如,一个排肥器转速报文可能这样组织:

// 变量施肥转速反馈报文示例(ID = 0x0CF00400)
// 数据场 8 字节
Byte[0] = 转速高字节;    // 0x00 - 0xFF
Byte[1] = 转速低字节;    // 0x00 - 0xFF
Byte[2] = 状态标志位;    // Bit0: 运行, Bit1: 故障
Byte[3] = 保留;
Byte[4] = 保留;
Byte[5] = 保留;
Byte[6] = 保留;
Byte[7] = 保留;

4.3.5 CRC场(循环冗余校验场)

CRC场包含15位CRC序列和1位CRC界定符(隐性位)。CRC计算覆盖SOF、仲裁场、控制场和数据场。接收节点计算本地CRC并与接收到的CRC序列比较,不一致则触发错误帧。

4.3.6 ACK场(应答场)

ACK场长度为2位:

  • ACK槽(1位):发送节点发送隐性位。任何正确接收到报文的节点,会在ACK槽期间发送显性位进行应答。
  • ACK界定符(1位):必须为隐性位,用于分隔。

4.3.7 EOF(帧结束)

EOF由7个隐性位构成。发送节点在EOF期间持续发送隐性位,表示帧传输结束。总线随后进入帧间空间(Interframe Space)。

4.4 远程帧、错误帧与过载帧

4.4.1 远程帧

远程帧的结构与数据帧几乎相同,区别在于:

  • RTR位为隐性(1)。
  • 数据场为空(DLC通常设置为0,但也可以设置DLC以指定期望的数据长度)。

远程帧用于请求数据。例如,主控制器可以发送一个ID为0x18FF5000的远程帧,请求排肥器发送当前状态。

4.4.2 错误帧

当任何节点检测到总线错误时,会立即发送错误帧。错误帧由两部分组成:

  1. 错误标志(Error Flag):6个连续显性位(主动错误)或6个连续隐性位(被动错误)。
  2. 错误界定符(Error Delimiter):8个隐性位。

错误帧会破坏当前正在传输的报文,迫使所有节点重新同步并重发。

4.4.3 过载帧

过载帧用于节点在接收数据时因内部处理延迟而请求总线暂停。其结构与错误帧类似:

  • 过载标志:6个显性位。
  • 过载界定符:8个隐性位。

过载帧只能在帧间空间发送,不能与数据帧同时发送。

4.5 帧间空间(Interframe Space)

任何帧(数据帧、远程帧、错误帧、过载帧)结束后,总线必须经历一段帧间空间才能开始下一帧传输。帧间空间包含:

  • 间歇场(Intermission):3个隐性位。
  • 总线空闲(Bus Idle):任意长度的隐性位,直到有节点开始发送SOF。
帧间空间与帧序列 前一帧 间歇 3 bit 总线空闲 任意长度 下一帧 注意:过载帧只能在间歇场期间发送。错误帧可以随时发送,不受帧间空间限制。

4.6 实战要点总结

常见误区:
  • 误以为远程帧的数据场可以携带数据——远程帧的数据场始终为空。
  • 忽略CRC校验——虽然硬件自动处理,但固件应检查CAN控制器的错误状态寄存器,防止错误数据被应用层使用。
  • DLC设置与实际数据长度不匹配——接收方会按照DLC读取数据,如果DLC大于实际有效数据,多余字节为未定义值。