3. CAN总线基础

在无人机设备驱动开发中,CAN总线承担着飞控、电调、云台、电池管理、传感器等节点之间的实时通信任务。理解CAN协议底层机制,是编写稳定驱动、定位总线异常、优化通信实时性的前提。本节围绕帧格式、仲裁、错误处理、位定时与同步以及标准帧与扩展帧差异展开,为后续寄存器配置与驱动实现打基础。

一、CAN协议帧格式:数据帧是通信主体

CAN 2.0B协议定义了四种帧类型:数据帧、远程帧、错误帧和过载帧。其中数据帧用于节点发送数据,是驱动开发中最常处理的对象。一个标准数据帧由七个字段组成:帧起始(SOF)、仲裁场、控制场、数据场、CRC场、应答场(ACK)和帧结束(EOF)。

  • 帧起始:1位显性电平,用于硬同步,表示帧开始。
  • 仲裁场:标准帧为11位标识符+RTR位;扩展帧为29位标识符+SRR+IDE+RTR。
  • 控制场:包含IDE位、保留位和4位数据长度码(DLC),DLC取值0~8,表示数据场字节数。
  • 数据场:0~8字节有效载荷,无人机中常用于传输姿态、转速、电压、温度等。
  • CRC场:15位CRC序列+1位CRC界定符,用于校验传输错误。
  • 应答场:发送节点发隐性位,接收节点正确接收后拉低为显性位,表示确认。
  • 帧结束:7位隐性位,标志帧结束。

下面用一张结构图直观展示标准数据帧与扩展数据帧的字段布局差异,便于在驱动中正确解析和填充寄存器。

CAN 2.0B 数据帧字段结构对比 标准帧(11位ID) SOF 仲裁场 11位ID + RTR 控制场 IDE + DLC 数据场 0~8 字节 CRC场 ACK EOF 扩展帧(29位ID) SOF 仲裁场 11位ID + SRR + IDE + 18位ID + RTR 控制场 IDE + DLC 数据场 0~8 字节 CRC场 ACK EOF 说明:扩展帧在仲裁场中插入SRR与IDE位,并将标识符扩展为29位,其余字段与标准帧基本一致。

二、仲裁机制:非破坏性逐位仲裁

CAN总线采用多主结构,任意节点在总线空闲时均可发起发送。当多个节点同时发送时,通过“线与”逻辑进行逐位仲裁:显性位(逻辑0)会覆盖隐性位(逻辑1)。节点在发送每一位的同时回读总线电平,若发现自身发送隐性位而总线为显性位,则立即退出仲裁,转为接收状态,且不会破坏已获胜节点的报文。

仲裁从标识符最高位开始逐位比较,ID数值越小(显性位越多)优先级越高。因此,在无人机系统中,飞控指令、急停信号通常分配低ID,而日志、状态上报分配高ID。仲裁失败节点会在下一帧继续尝试,无需重传当前帧,这是CAN实时性的重要保障。

仲裁只发生在仲裁场和ACK场之前,一旦进入数据场,所有节点均已确定主从关系,不再发生仲裁。

三、错误处理:五类错误与三种状态

CAN节点内置错误检测机制,可检测位错误、填充错误、CRC错误、格式错误和应答错误。每个节点维护发送错误计数器(TEC)和接收错误计数器(REC),并据此在错误主动、错误被动和总线关闭三种状态间迁移。

错误类型检测位置典型原因
位错误发送节点回读总线电平与发送值不一致
填充错误位填充区域连续6个相同电平
CRC错误CRC场传输干扰或波特率不匹配
格式错误固定格式场帧结构不符合协议
应答错误ACK场无节点正确接收

当TEC或REC超过127时,节点进入错误被动状态,发送错误帧时只能发被动错误标志;当TEC超过255时,节点进入总线关闭状态,必须通过软件或硬件复位才能恢复。驱动开发中应监控错误计数器,及时上报总线健康状态。

// 示例:读取CAN错误计数器(伪代码)
uint8_t tec = CAN_GetTEC(CAN1);
uint8_t rec = CAN_GetREC(CAN1);
if (tec > 127 || rec > 127) {
    CAN_ReportErrorState(CAN1, ERROR_PASSIVE);
}
if (tec > 255) {
    CAN_RequestBusOffRecovery(CAN1);
}

四、位定时与同步:保证采样点一致

CAN总线没有独立时钟线,所有节点必须依靠位定时逻辑对位流进行同步。一个位时间被划分为同步段(SYNC_SEG)、传播段(PROP_SEG)、相位缓冲段1(PHASE_SEG1)和相位缓冲段2(PHASE_SEG2)。采样点位于PHASE_SEG1结束处,通常设置在位时间的75%~87.5%位置。

同步分为硬同步和重同步。硬同步发生在帧起始,强制将位时间边界对齐到SOF下降沿;重同步发生在帧内,通过调整PHASE_SEG1和PHASE_SEG2长度补偿节点间时钟偏差。位定时参数由波特率预分频器(BRP)、TSEG1、TSEG2和SJW共同决定,配置不当会导致采样点漂移,引发随机错误帧。

无人机中飞控与电调若使用不同晶振,必须重新计算位定时参数,不能直接套用同一组BRP/TSEG值,否则长线通信时误码率会明显上升。

五、标准帧与扩展帧区别及选型建议

标准帧使用11位标识符,扩展帧使用29位标识符。扩展帧在仲裁场中通过SRR和IDE位与标准帧区分,IDE为显性表示标准帧,隐性表示扩展帧。两者可在同一总线上共存,但标准帧优先级天然高于扩展帧,因为标准帧的IDE位为显性。

  • 标准帧:开销小、仲裁快,适合无人机中高频控制指令、电机转速等实时性要求高的场景。
  • 扩展帧:标识符空间大,适合多节点、多参数、需要复杂寻址的电池管理或云台控制场景。
  • 混合使用:需统一规划ID分配表,避免标准帧与扩展帧ID冲突,并注意过滤器配置。

实际项目中,建议先根据节点数量和报文类型确定帧格式,再编写ID分配表,最后配置CAN控制器的验收滤波器。若总线负载率超过70%,应优先优化报文周期或改用扩展帧分组,而不是盲目提高波特率。

复盘要点:多数CAN通信异常并非驱动逻辑错误,而是位定时参数不匹配、终端电阻缺失或ID优先级规划不合理。调试时先用示波器观察总线电平与采样点,再检查错误计数器,往往比直接改代码更高效。