4、错误检测机制:发送器与接收器的错误检测方法、错误标志的生成与传播、错误帧的结构与作用

CAN总线之所以能在工业现场、车载网络等强电磁干扰环境中可靠运行,其核心支柱之一便是完备的错误检测与自愈机制。与TCP/IP协议栈中依赖上层校验和重传不同,CAN协议在数据链路层就内建了多维度、分布式的错误检测体系。每一个节点(无论是发送器还是接收器)都独立地对总线上的电平与协议规则进行实时监督,一旦发现违规,立即生成错误标志,中断当前帧的传输,并通过“错误帧”通知所有节点丢弃该帧。这种机制确保了错误帧不会被任何节点误接收,从而维护了数据的一致性。本章将深入剖析发送器与接收器的五种错误检测方法、错误标志的生成与传播过程,以及错误帧的结构与作用。

CAN总线错误检测与错误帧传播机制 发送器节点 ① 位监控(发送电平对比) ② 位填充规则(连续5个同极性) ③ CRC15 校验序列计算 ④ 应答检查(ACK Slot) ⑤ 格式检查(固定位电平) 错误计数 +8 / +16 接收器节点 ① 位填充规则检查 ② CRC15 本地计算比对 ③ 应答检查(发送显性ACK) ④ 格式检查(固定位电平) ⑤ 位监控(仅对显性位) 错误计数 +1 CAN_H / CAN_L 差分总线 帧传输与应答 错误标志生成与传播 检测到错误 → 主动错误标志(6个显性位) 或被动错误标志(6个隐性位) 错误帧结构 错误标志 6位 错误界定符 8位隐性 总线空闲 ≥3位隐性 所有节点同时检测错误 → 各自发送错误标志 → 叠加后总线呈现6~12个显性位

4.1 发送器的错误检测方法

发送器是总线上的“主动方”,它对自身发送的每一位都负有监督责任。CAN协议为发送器设计了五种独立的检测机制,这些机制并行工作,任何一项触发都会导致错误处理流程的启动。

4.1.1 位监控(Bit Monitoring)

这是发送器独有的检测手段。发送器在发送每一位(无论是显性0还是隐性1)的同时,通过收发器持续读取总线上的实际电平,并将“发送电平”与“回读电平”进行逐位比较。如果两者不一致,发送器立即判定为位错误(Bit Error)。例如,发送器发送显性位(0),但回读到隐性位(1),说明总线被其他节点干扰或自身驱动能力不足。位监控覆盖整个帧的发送过程,包括仲裁场、控制场、数据场、CRC场和ACK场。

4.1.2 位填充规则检查(Bit Stuffing Rule)

CAN协议规定,在帧起始(SOF)到CRC序列结束之间,如果连续出现5个相同极性的位,发送器必须自动插入一个反极性的填充位。发送器在发送过程中需要持续自检:是否在连续5个相同位后正确插入了填充位?如果发送器发现自己漏插或错插,则构成填充错误(Stuff Error)。这一机制保证了总线上的电平有足够的跳变沿,便于接收器提取同步时钟。

4.1.3 CRC15 校验序列计算

发送器在发送CRC序列之前,会基于帧起始、仲裁场、控制场和数据场的内容,通过多项式 x¹⁵ + x¹⁴ + x¹⁰ + x⁸ + x⁷ + x⁴ + x³ + 1 计算出一个15位的CRC校验值。发送器将计算值与即将发送的CRC序列进行比对,若发现不一致(理论上极难发生,但硬件故障可能导致),则判定为CRC错误。

4.1.4 应答检查(ACK Check)

在ACK场中,发送器发送一个隐性位(ACK Slot),然后释放总线控制权。所有正确接收该帧的接收器必须在这个时隙内发送一个显性位(0)作为应答。发送器在ACK Slot期间回读总线电平:如果读到显性位,说明至少有一个节点正确接收;如果读到隐性位,说明没有任何节点正确接收,发送器判定为应答错误(ACK Error)。

4.1.5 格式检查(Form Check)

CAN帧中某些位具有固定的电平值,例如CRC界定符必须是隐性位,ACK界定符必须是隐性位,EOF(帧结束)必须是7个连续的隐性位。发送器在发送这些固定位时,会检查自身发送的电平是否符合协议规定,若不符合则判定为格式错误(Form Error)。

发送器错误计数规则:发送器检测到位错误、填充错误、格式错误或ACK错误时,错误计数加8;检测到CRC错误时,错误计数加16。当错误计数超过255时,节点进入总线关闭(Bus-Off)状态。

4.2 接收器的错误检测方法

接收器虽然不主动驱动总线(除ACK应答外),但同样承担着严格的监督职责。接收器的检测方法侧重于对接收到的位流进行协议合规性验证。

4.2.1 位填充规则检查

接收器在接收过程中,持续统计连续相同极性的位数。如果发现连续出现6个相同极性的位(即缺少应有的填充位),则判定为填充错误。这一检查覆盖从SOF到CRC序列结束的所有位。

4.2.2 CRC15 本地计算比对

接收器在接收完数据场后,使用与发送器相同的多项式,对已接收的位流(SOF到数据场)进行本地CRC计算。当CRC序列到达时,接收器将本地计算结果与接收到的15位CRC值进行逐位比较。任何一位不匹配,即判定为CRC错误。CRC错误是接收器最常检测到的错误类型之一,通常由总线干扰或信号质量劣化引起。

4.2.3 应答检查

接收器在ACK Slot期间,如果正确接收了帧(未检测到其他错误),则必须主动发送一个显性位作为应答。如果接收器自身检测到错误,则不应发送应答位,保持隐性电平。接收器同时也会检查ACK Slot的电平是否符合预期:如果自己发送了显性应答但回读到隐性,说明总线驱动异常。

4.2.4 格式检查

接收器对帧中的固定位进行电平验证,包括CRC界定符(必须为隐性)、ACK界定符(必须为隐性)以及EOF(必须为7个隐性位)。任何固定位电平不符合协议,即判定为格式错误。

4.2.5 位监控(仅对显性位)

接收器在发送ACK显性位时,会监控总线电平。如果发送显性位但回读到隐性位,说明总线被其他节点拉低或自身驱动失败,判定为位错误。此外,接收器在总线空闲状态检测到显性位时,视为帧起始,无需额外监控。

检测方法 发送器 接收器 错误计数增量 典型触发原因
位监控 ✅ 逐位对比 仅ACK时 发送器+8 总线短路、收发器故障
位填充规则 ✅ 发送自检 ✅ 接收检查 发送器+8 / 接收器+1 时钟漂移、干扰导致位翻转
CRC15校验 ✅ 计算比对 ✅ 本地计算比对 发送器+16 / 接收器+1 电磁干扰、信号反射
应答检查 ✅ 回读ACK Slot ✅ 发送应答 发送器+8 无接收器在线、接收器错误
格式检查 ✅ 发送固定位 ✅ 接收固定位 发送器+8 / 接收器+1 协议违规、总线竞争异常

4.3 错误标志的生成与传播

当任何节点(发送器或接收器)检测到错误后,并不会立即停止操作,而是立即启动错误帧的发送流程。错误标志的生成与传播遵循“先到先发、叠加增强”的原则。

4.3.1 主动错误标志(Active Error Flag)

处于主动错误状态(错误计数 ≤ 127)的节点检测到错误后,会发送6个连续的显性位(0)。这6个显性位故意违反了位填充规则(连续6个相同位),从而强制总线上所有其他节点也检测到填充错误,进而同步进入错误处理流程。主动错误标志具有“破坏性”,它会覆盖正在传输的帧数据,确保错误帧不会被任何节点误接收。

4.3.2 被动错误标志(Passive Error Flag)

处于被动错误状态(128 ≤ 错误计数 ≤ 255)的节点检测到错误后,只能发送6个连续的隐性位(1)。被动错误标志不具备破坏性,如果总线上其他节点正在发送显性位,被动错误标志会被“淹没”。因此,被动错误节点需要等待总线空闲后,才能重新尝试发送。这一机制防止了故障节点持续破坏总线通信。

4.3.3 错误标志的传播叠加

当第一个节点发送主动错误标志(6个显性位)时,其他节点在接收这6个显性位的过程中,会因违反位填充规则而检测到填充错误,从而也各自发送自己的错误标志。由于所有错误标志都是显性位,它们在总线上进行“线与”叠加,最终总线上呈现的显性位长度可能为6到12位不等。这种叠加效应确保了即使某个节点因故障无法正确检测错误,也能通过其他节点的错误标志感知到错误发生。

工程经验:在CAN总线调试中,如果使用示波器捕获到连续6~12个显性位后紧跟8个隐性位,即可确认这是错误帧。通过分析错误帧出现的位置(例如是否总在特定ID的帧之后),可以快速定位故障节点或干扰源。

4.4 错误帧的结构与作用

错误帧是CAN协议中唯一由硬件自动生成的帧类型,不需要软件参与。它的结构非常简单,由两部分组成:错误标志和错误界定符。

4.4.1 错误帧的完整结构

  • 错误标志(Error Flag):6位。主动错误节点发送6个显性位,被动错误节点发送6个隐性位。叠加后总线上可能呈现6~12个显性位。
  • 错误界定符(Error Delimiter):8位隐性位。用于将错误帧与后续的总线空闲状态分隔开,防止错误标志与下一帧的SOF混淆。

错误帧发送完成后,总线进入至少3位隐性位的空闲状态,之后所有节点可以重新开始仲裁和发送。被错误帧中断的原数据帧将被所有节点丢弃,发送器不会自动重发(除非上层协议如CANopen、J1939实现应用层重传机制)。

4.4.2 错误帧的作用

  1. 全局帧丢弃:错误帧确保所有节点都意识到当前帧无效,从而不会将损坏的数据提交给上层应用。
  2. 故障隔离:通过错误计数机制,持续产生错误的节点会从主动错误状态降级为被动错误状态,最终进入总线关闭状态,实现故障节点的自动隔离。
  3. 总线同步恢复:错误帧的界定符和随后的总线空闲状态,为所有节点提供了重新同步的机会,使总线通信能够快速恢复。

4.5 案例拆解:总线干扰导致的错误帧风暴

场景背景:某工业自动化产线采用CAN总线连接PLC、伺服驱动器和远程IO模块,波特率500kbps,总线长度约80米。产线调试期间,发现伺服驱动器启动时,PLC偶尔报“接收超时”错误,且故障频率与伺服电机转速正相关。

初始现象:使用CAN分析仪抓取总线报文,发现伺服启动瞬间出现大量错误帧,错误帧之间夹杂着ID为0x181的伺服状态报文。错误帧的显性位长度约为8~10位,随后紧跟8个隐性位。

关键数据:

  • 错误帧出现频率:约200帧/秒(伺服运行时)
  • 错误类型分布:CRC错误占70%,填充错误占25%,格式错误占5%
  • 总线信号质量:示波器测量发现伺服驱动器端的CAN_H对地存在约±2V的振铃,幅值超过CAN收发器的共模输入范围

分析判断过程:错误帧的显性位长度超过6位,说明有多个节点同时发送了错误标志,属于典型的“错误传播叠加”。CRC错误占比最高,表明数据在传输过程中发生了位翻转,而非协议逻辑错误。示波器波形显示振铃发生在伺服驱动器内部开关管动作时刻,推测是伺服驱动器的功率电路通过寄生电容耦合到CAN收发器,导致信号质量劣化。

实际操作步骤:

  1. 在伺服驱动器端的CAN_H和CAN_L线上分别串联共模电感(型号:TDK ACT45B-510-2P,阻抗90Ω@100MHz)。
  2. 在伺服驱动器CAN收发器的VCC与GND之间增加100nF高频去耦电容,并靠近收发器引脚放置。
  3. 将CAN总线屏蔽层在PLC端单点接地,避免形成地环路。
  4. 将总线终端电阻从60Ω(两端各120Ω并联)调整为伺服驱动器端单独使用120Ω,PLC端使用可调终端电阻并匹配实际线缆阻抗。

结果对比:整改后,错误帧完全消失,PLC接收超时报警不再出现。总线信号质量改善为:振铃幅值降至±0.5V以内,信号边沿单调,满足ISO 11898-2规范要求。

风险与代价:共模电感的引入增加了约0.5μs的信号传播延迟,对于500kbps的波特率(位时间2μs)而言,延迟占比25%,仍在协议允许的采样点容差范围内。如果总线长度进一步增加或波特率提升至1Mbps,需要重新评估信号延迟的影响。

复盘经验:错误帧的分布特征是故障诊断的重要线索。CRC错误为主时,优先排查信号完整性和电磁干扰;填充错误为主时,优先检查节点时钟精度和位时序配置;格式错误为主时,优先检查协议实现和收发器兼容性。

风险提示:不要试图通过软件屏蔽错误帧来“解决问题”。错误帧是CAN协议的自保护机制,屏蔽错误帧会导致损坏的数据被上层应用接收,可能引发设备误动作甚至安全事故。正确的做法是定位并消除错误产生的根源。

4.6 常见误区与总结复盘

误区一:认为错误帧是“坏节点”发送的。实际上,任何节点(包括正常节点)在检测到错误后都会发送错误标志。错误帧是节点的集体响应,而非单一故障节点的行为。

误区二:混淆“错误帧”与“过载帧”。错误帧用于报告已检测到的错误,而过载帧用于请求延迟后续帧的发送(例如接收器内部缓冲区忙)。两者结构不同,触发条件也不同。

误区三:忽视被动错误状态的影响。被动错误节点发送的错误标志是隐性位,不具备破坏性。如果总线上同时存在主动错误节点和被动错误节点,被动错误节点的错误标志可能被覆盖,导致其错误计数持续增加,最终进入总线关闭状态。在总线设计中,应尽量避免节点长期处于被动错误状态。

误区四:认为发送器会自动重发错误帧。CAN协议本身不提供自动重发机制。被错误帧中断的帧不会自动重发,除非上层应用协议(如CANopen的SDO块传输、J1939的传输协议)实现了应用层重传。对于关键控制数据,建议在应用层设计超时重发或冗余发送机制。

总结:CAN总线的错误检测机制是一个多维度、分布式的闭环系统。发送器通过位监控、填充规则、CRC、应答和格式检查确保自身发送的正确性;接收器通过填充规则、CRC、应答和格式检查验证接收数据的完整性。错误标志的生成与传播实现了错误的快速广播和帧的全局丢弃,而错误帧的结构设计则保证了错误处理后的总线快速恢复。理解这一机制,是进行CAN总线故障诊断、网络设计和可靠性优化的基础。