Chapter 05 · CAN 总线 / 汽车电子

错误处理机制

CAN 的可靠性传奇,靠的是一套精密的差错检测与故障界定机制。本章讲透五种错误、错误帧、TEC/REC 计数器与"错误主动→被动→总线关闭"三态状态机。

课程进度31%

关键概念

位错误 (Bit Error)
发送节点在发送某位的同时监听总线,若发出的电平与回读电平不一致,即为位错误。例外:仲裁场发隐性读到显性属正常的仲裁失利,ACK 槽发隐性读到显性属正常应答,这两处不算位错误。位错误主要捕捉"我发了却没能驱动成功"的硬件/竞争问题。
填充错误 (Stuff Error)
在需要位填充的场(SOF~CRC 序列)中,若检测到连续 6 个相同电平的位,说明位填充规则被破坏(本应在第 6 位前插入相反填充位),判为填充错误。它既能捕捉真正的传输错误,也是错误帧(6 显性位)能被全网识别的原因。
CRC 错误 (CRC Error)
接收方对收到的 SOF~数据场重新计算 15 位 CRC,与帧中携带的 CRC 序列比对,不一致即 CRC 错误。这是检测能力最强的一层,能发现突发和随机位翻转。CRC 错误由接收方在 CRC 界定符之后的位置发出错误帧标记。
形式错误 (Form Error)
固定格式的场(CRC 界定符、ACK 界定符、EOF)本应是固定的隐性位,若在这些位置检测到显性位,即形式错误。它保护帧的"骨架"不被破坏。注意某些实现对 EOF 最后一位有宽容处理以避免误判。
应答错误 (ACK Error)
发送方在 ACK 槽发送隐性,期望有接收方覆写显性;若读回仍是隐性,说明没有任何节点正确接收本帧,判为应答错误。常见于总线上只有发送方一个节点、波特率不匹配、或所有接收方都检出了错误。
错误帧 (Error Frame)
任何检出错误的节点立即发送错误帧来通告全网并作废当前帧。它由错误标志(6 个相同电平位)+ 错误界定符(8 个隐性位)组成。主动错误标志是 6 个显性位——故意违反位填充,使全网都检出填充错误并跟着发错误标志,从而一致地丢弃该帧、由发送方重发。
TEC / REC (发送/接收错误计数器)
TEC(Transmit Error Counter)与 REC(Receive Error Counter)是每个节点内部的两个计数器。检出错误时按规则增加(发送出错 +8,接收出错 +1),成功收发一帧则减少(−1)。这套"出错涨得快、正常降得慢"的记分制,用来量化一个节点的健康程度,并驱动故障界定状态机。
故障界定 (Fault Confinement)
CAN 的自我保护机制:根据 TEC/REC 值把节点分为错误主动、错误被动、总线关闭三态。它的目的是让"经常出错的坏节点"逐步降低对总线的影响,最终自我隔离(总线关闭),从而保护整个网络不被一个故障节点拖垮。这是 CAN 高可靠性的核心设计。

五种错误类型速查

错误类型检出者触发条件典型原因
位错误 Bit发送方发出电平≠回读电平(仲裁/ACK 除外)硬件故障、多驱动冲突
填充错误 Stuff收发双方需填充区出现 6 连同干扰、错误帧标志
CRC 错误接收方重算 CRC≠帧内 CRC数据场位翻转
形式错误 Form收发双方固定隐性位出现显性界定符/EOF 被破坏
应答错误 ACK发送方ACK 槽读回隐性(无人应答)孤立节点、波特率不符
五重防护的意义

这五种检测互为补充:CRC 抓数据内容错误,位/形式错误抓电平级异常,填充错误兼顾同步与内容,ACK 错误确认送达。它们让 CAN 的残余错误概率(未检出错误)极低(约 10−11 量级)。一旦任一检测命中,检出节点立即发错误帧作废本帧,发送方随后自动重传——错误恢复对上层应用几乎透明。

错误帧的结构

主动错误帧(Active Error Frame) ══════════════════════════════════════════════════ 正常帧被打断 ...数据位... │错误标志(6 显性)│叠加区│错误界定符(8 隐性)│IFS │0 0 0 0 0 0 │ │1 1 1 1 1 1 1 1 │ ▲ 6 个显性位故意违反位填充(连续>5) ⇒ 其它节点检出"填充错误" ⇒ 也各自发出错误标志(可能叠加成 6~12 显性位) ⇒ 全网一致丢弃该帧 被动错误帧(Passive Error Frame) 错误被动节点发出的错误标志是 6 个隐性位, 不会主动破坏总线 ⇒ 对正常通信几乎无影响 (这正是"被动"的含义:出错了也只是默默记账,不搅局)

三态故障界定状态机

节点根据 TEC/REC 在三种状态间转移。核心阈值是 128(主动↔被动)与 256(进入总线关闭)。

CAN 故障界定状态机 ═══════════════════════════════════════════════════════ TEC≤127 且 REC≤127 ┌───────────────────────┐ │ 错误主动 (Error Active) │ 正常工作状态 │ 出错发"主动错误帧" │ 6 显性标志,参与仲裁 └───────────┬───────────┘ │ TEC>127 或 REC>127 ▼ ┌───────────────────────┐ │ 错误被动 (Error Passive) │ 仍能收发 │ 出错发"被动错误帧" │ 6 隐性标志,不搅局 │ 发送后需额外等 8 位间隔 │ 优先级被"惩罚" └───────────┬───────────┘ │ TEC ≥ 256 ▼ ┌───────────────────────┐ │ 总线关闭 (Bus-Off) │ 彻底退出总线 │ 不发送、不应答、不影响 │ 自我隔离,保护全网 └───────────┬───────────┘ │ 监测到 128 次 11 连隐性(总线空闲) │ + 软件/硬件复位 CAN 外设 ▼ 回到 错误主动(TEC/REC 清零) 计数规则(简化): 发送错误 TEC+=8; 接收错误 REC+=1; 成功收发一帧 对应计数 −1
状态进入条件能否收发错误标志对总线影响
错误主动TEC≤127 且 REC≤127正常收发6 显性位正常参与,出错会打断总线
错误被动TEC>127 或 REC>127可收发但受罚6 隐性位出错不搅局,发送后额外等待
总线关闭TEC≥256完全退出自我隔离,不影响其它节点
总线关闭:坏节点的最后一道闸

当一个节点反复发送失败(TEC 累加到 ≥256),它进入总线关闭,主动闭嘴、不再干扰总线,这样即使它硬件损坏也不会拖垮整个网络。恢复需要满足条件(总线上出现 128 次连续 11 个隐性位,即总线恢复正常一段时间)并由软件重新初始化 CAN 外设。在实际项目里,进入 Bus-Off 通常意味着严重物理问题(终端电阻缺失、波特率错配、线路短路),应记录诊断故障码并触发恢复流程,而不是简单地无限重启。

软件层面:监测状态与 Bus-Off 恢复

在 STM32 HAL 中可读取错误计数器并处理 Bus-Off 恢复:

/* 读取错误状态与计数器 */
uint32_t esr = CAN1->ESR;   /* Error Status Register */
uint8_t tec = (esr >> 16) & 0xFF;  /* 发送错误计数器 TEC */
uint8_t rec = (esr >> 24) & 0xFF;  /* 接收错误计数器 REC */

if (esr & CAN_ESR_BOFF) {          /* 已进入总线关闭 */
    /* 记录诊断故障码,排查物理层 */
    log_dtc(DTC_CAN_BUSOFF, tec, rec);

    /* 恢复:ABOM=1 可自动恢复;否则手动重启外设 */
    HAL_CAN_Stop(&hcan);
    HAL_CAN_Start(&hcan);       /* 重新进入总线 */
}
else if (esr & CAN_ESR_EPVF) {     /* 错误被动标志 */
    /* 告警:链路质量下降,TEC/REC 超过 127 */
    warn_link_degraded(tec, rec);
}
ABOM 自动恢复位

bxCAN 的 MCR.ABOM(Automatic Bus-Off Management)位置 1 时,控制器在进入 Bus-Off 后会自动等待恢复条件满足并重新上线,无需软件干预。置 0 则需软件手动 Stop/Start。生产代码常开启 ABOM 以保证瞬时故障后自动复位,但同时应记录 Bus-Off 次数用于诊断——频繁 Bus-Off 是硬件问题的强信号。

本章小结

CAN 用五种错误检测构筑可靠性:位错误(发送电平≠回读,仲裁/ACK 除外)、填充错误(需填充区 6 连同)、CRC 错误(重算 CRC 不符)、形式错误(固定隐性位出现显性)、应答错误(ACK 槽无人覆写显性)。任一命中,检出节点立即发错误帧——主动错误标志是 6 个显性位,故意违反位填充让全网一致检错并丢弃该帧,发送方随后自动重传,对上层透明。每个节点维护 TEC/REC 两个计数器(出错涨得快、正常降得慢),驱动故障界定三态状态机:TEC/REC≤127 为错误主动(正常,发显性错误标志);超 127 转错误被动(仍收发但发隐性错误标志、发送后额外等待受罚);TEC≥256 进入总线关闭(彻底自我隔离保护全网,需总线恢复正常且软件重初始化才能回到主动态)。ABOM 位可让 bxCAN 自动恢复。频繁 Bus-Off 往往指向终端电阻缺失、波特率错配或线路短路等严重物理问题,应记录诊断码而非盲目重启。

⚒️ 配套开发者工具箱 · JSON / 正则 / 时间戳 / Cron 等 17 款免费在线工具