☰
CAN练习
2026/9/29 5:17:43 网站建设 项目流程

疑惑

问:发 1 帧报文,最多 TEC+8吗

答:错,报文传输过程中,每检测到一个总线错误,都会触发一次 TEC 累加。 一整帧 CAN 报文很长(SOF+ID+DLC + 数据 + CRC+ACK),只要总线波形畸变,这一帧报文在传输途中会连续报好几个填充错误,每检出 1 个错误,TEC 就 + 8

问:为什么tec和rec最大只有128

答:硬件限制寄存器使用7bit,f1/4有这个限制,h7没有。所以f1/4不会进入BusOff

注意:重定向printf要打开Micro LIB

CAN-1:双节点基础通信

参数:sFilterConfig.SlaveStartFilterBank = 14;

含义:(硬件基础要有两个CAN)

  • CAN1(主)使用过滤器0 ~ 13(一共 14 组)
  • CAN2(从)使用过滤器14 ~ 27(一共 14 组)

启动CAN接收通知(开启接收中断)

HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);

CAN-2:使用DBC

DBC 全称:Database CAN

简单一句话:DBC 是 CAN 总线的报文描述文件(后缀.dbc),是车载 CAN 的 “翻译字典”,由 Vector 公司定义的文本格式。

核心作用

CAN 总线原始传输的只有十六进制字节流,比如:ID:0x123 Data: 08 00 40 1F ...单纯看这串数字,你不知道哪几个字节代表发动机转速、水温、车速。 DBC 文件里面写好了一套规则,用来把原始 CAN 数据翻译成工程值(物理量)。

DBC 里面存了哪些信息

  1. Message(报文)
    • 报文 ID、报文名称、周期(周期报文)、数据长度 DLC
    • 例如:EngineMsg : 0x0A0, DLC=8
  2. Signal(信号)
    • 信号名称:EngineRPM、VehicleSpeed
    • 起始位、信号长度、字节序 (Intel/Motorola)、数据类型 (有符号 / 无符号)
    • 缩放因子、偏移量:物理值 = 原始值 × 缩放 + 偏移
    • 最小值、最大值、单位(RPM、km/h、℃)
  3. 附加内容:注释、节点(Node,ECU)、值表(枚举,比如 0 = 关闭,1 = 开启)

DBC 基础语法结构

DBC =Database CAN,CAN 总线数据库文件,纯文本,后缀.dbc,ZCANPRO 可以直接导入,自动解析 CAN 报文、信号、缩放偏移。

规则:信号位序是 Motorola (大端)/Intel (小端),车载常用 Motorola(ZCANPRO 里可以选择字节序)

1. 文件头部信息段(必写)

VERSION "demo_can" NS_ : NS_DESC_ : CM_ : BA_DEF_ : BA_ : VAL_ :
关键字英文全称作用
VERSIONVersionDBC 版本名称,字符串,随便写,ZCANPRO 仅展示
NS_Namespace命名空间,固定写NS_ :,DBC 标准保留,几乎不用改
NS_DESC_Namespace Description命名空间描述,一般空着
CM_Comment注释,给报文 / 信号加说明文字
BA_DEF_Attribute Definition属性定义,自定义 DBC 的属性(如报文周期、ECU 名称)
BA_Attribute属性值,给上面定义的属性赋值
VAL_Value信号枚举值,比如 0=Off,1=On,ZCANPRO 解析后显示文字而不是原始数字

2. 节点定义BU_

BU_=Bus Unit总线单元,代表总线上的 ECU(节点) 语法:

BU_: ECU1 CANAnalyzer

含义:总线上有 2 个节点:ECU1(STM32)、CANAnalyzer(ZCANPRO 分析仪)

注意:名字不能有空格

BU_后面跟所有参与 CAN 收发的 ECU 名称。


3. 报文定义BO_【核心!BO = Message / Board Message】

BO_=Board Object报文对象,代表一帧 CAN 报文 语法模板:

BO_ 100 EngineMsg: 8 ECU1 SG_ EngineRPM : 0|16@0+ (1,0) [0,8000] "rpm" CANAnalyzer SG_ Temp : 16|8@0+ (1,-40) [-40,125] "degC" CANAnalyzer
BO_ 行拆解

BO_ 100 EngineMsg: 8 ECU1

  1. BO_:Board Object,报文起始标记
  2. 100:CAN ID,十进制!注意 DBC 里 ID 默认十进制,不是十六进制!

    CAN ID 0x100,DBC 里要写 256,ZCANPRO 导入这点很容易踩坑

  3. EngineMsg:报文名称,自定义
  4. 8:报文数据长度 DLC,0~8,CAN2.0 最多 8 字节
  5. ECU1:发送该报文的节点(发送方 ECU)
SG_ 信号行 SG = Signal

SG_ EngineRPM : 0|16@0+ (1,0) [0,8000] "rpm" CANAnalyzerSG_=Signal信号,报文中提取的一个物理量

表格

片段含义
EngineRPM信号名
`016`` 起始位信号长度 bit`,从 bit0 开始,占 16bit
@0字节序:0=Motorola 大端;1=Intel 小端(车载 CAN 大多 Motorola)
+符号:+= 无符号 unsigned;-= 有符号 signed
(1,0)(缩放因子Factor,偏移Offset)物理值 = 原始整数 × Factor + Offset
[0,8000]物理值范围[最小值,最大值],ZCANPRO 用来校验
"rpm"单位字符串
CANAnalyzer接收这个信号的节点(接收方 ECU)

Motorola (大端 @0):高位放在低字节,车载 ECU 最常用,ZCANPRO 解析车载 DBC 默认这个。 Intel (@1):小端,低位放低字节,单片机裸机代码常用。

注释 CM_ (CM=Comment)

CM_ "发动机报文,周期100ms";CM_ SG_ 100 EngineRPM "发动机转速";给报文或者信号写备注,ZCANPRO 里可以看到说明。


4. 属性定义 BA_DEF_ / BA_(BA=Attribute)

常用:定义报文周期,ZCANPRO 可以读取周期信息

BA_DEF_ BO_ "GenMsgCycleTime" INT 0 5000; BA_ "GenMsgCycleTime" BO_ 100 100;
  • BA_DEF_ BO_ "GenMsgCycleTime" INT 0 5000;BA_DEF_ = Attribute Definition,定义一个报文属性GenMsgCycleTime(报文周期),整数,范围 0~5000ms
  • BA_ "GenMsgCycleTime" BO_ 100 100;BA_ = Attribute,给 ID=100 报文赋值:周期 100ms,ZCANPRO 可以展示报文周期

5. 枚举 VAL_ (VAL=Value)

信号数值映射文字,ZCANPRO 解析直接显示文本,不用看原始数字

VAL_ 100 Gear 0 "N" 1 "D" 2 "R" ;

含义:报文 ID100 里的信号 Gear,0=N 挡,1=D 挡,2=R 挡。


6. 完整可直接导入 ZCANPRO 的最小 DBC 示例

新建文本,复制下面全部内容,保存为demo.dbc,直接拖进 ZCANPRO 即可

VERSION "DemoCAN" NS_ : NS_DESC_ : CM_ : BA_DEF_ : BA_ : VAL_ : BU_: ECU1 CANAnalyzer BO_ 256 EngineMsg: 8 ECU1 SG_ EngineRPM : 0|16@0+ (1,0) [0,8000] "rpm" CANAnalyzer SG_ EngineTemp : 16|8@0+ (1,-40) [-40,125] "degC" CANAnalyzer CM_ BO_ 256 "发动机周期报文,100ms"; CM_ SG_ 256 EngineRPM "发动机转速"; BA_DEF_ BO_ "GenMsgCycleTime" INT 0 5000; BA_ "GenMsgCycleTime" BO_ 256 100;

错误解析

前置重要说明:

ZCANPRO 里的消极错误是软件中文翻译名词,≠ CAN 协议的被动错误状态 (Error Passive)。

CAN 协议规定两大类错误事件:

①仲裁丢失(Arbitration Lost):属于总线仲裁竞争失败,独立一类,不属于 “消极错误”;

②CAN 标准 5 类总线错误(消极错误字段描述的就是这 5 种):位错误、位填充错误、CRC 错误、ACK 错误、格式错误。 所以日志里会分成两组独立字段:消极错误相关字段+仲裁错误段表示,分开记录两类不同故障。

一、基础公共字段

  1. 序号:错误事件的流水编号,0、1 代表第 0、1 条捕获到的总线错误
  2. 源设备类型:USBCAN-II,代表这条错误是周立功 USBCAN-II 分析仪硬件采集上报
  3. 源设备 / 源通道:设备 0,通道 0 → 使用分析仪的第 0 号 CAN 通道抓包
  4. 时间:ZCANPRO 本地时间戳,捕获到这个错误的时刻
  5. 节点状态:CAN 节点错误状态机(CAN 2.0A/B 协议标准)
    • 主动状态 (Error Active):TEC<128,REC<128。节点可以正常收发报文;发送出错 TEC+8。
    • 被动状态 (Error Passive):TEC≥128 或 REC≥128。节点不能主动发送报文,只能接收;发送失败 TEC 只 + 1。
    • 总线关闭 (BusOff):TEC≥256,彻底脱离总线,只能接收复位后恢复。

    你的日志:TEC=127 还在主动;发生一次仲裁丢失,TEC+1 变成 128 → 切换被动状态。

  6. REC:Receive Error Counter,接收错误计数器收到报文出错时增加。你这里 REC 一直 = 0:接收报文全部正常,接收侧没有任何错误。
  7. TEC:Transmit Error Counter,发送错误计数器节点发送报文失败时增加。你的错误全部来自发送侧,所以 TEC 持续上涨,REC 不变。

二、【错误码】字段

含义:USBCAN-II 硬件寄存器原始错误值,是 CAN 控制器 ESR(错误状态寄存器)读取出来的十六进制原始数据,ZLG 硬件自定义编码。

  • 0x00000004:仲裁丢失事件(Arbitration Lost)
  • 0x00000010:发送错误标记,TEC 计数达到被动阈值后上报

作用:底层原始编号,用来区分错误大类,软件根据这个值解析后面的文字描述。

三、【消极错误代码类型】

针对5 类标准 CAN 总线错误做分类编号:位错误、位填充错误、CRC 错误、ACK 错误、格式错误。 编号1=其它错误

  • 什么时候不是其它错误:如果是位错误,这里会显示【位错误】;ACK 丢失就显示【ACK 错误】。
  • 本次场景:错误是仲裁丢失,仲裁丢失不属于这 5 类标准消极错误,所以归类为「其它错误」。

四、【消极错误属性】

标记这个标准总线错误发生在发送流程还是接收流程

  • 0:发送错误:错误发生在节点向外发送报文的过程,对应 TEC 累加
  • 1:接收错误:错误发生在接收报文,对应 REC 累加

你的日志全部是0:发送错误,代表所有错误都是发送报文的时候产生。

五、【消极错误段表示】

含义:仅针对 5 类标准 CAN 消极错误,记录错误发生在报文哪一段 CAN 报文分段:SOF 起始帧、仲裁段、控制段、数据段、CRC 段、ACK 段、EOF 帧结束。

  • 如果是 ACK 错误,这里会标记在 ACK 段;位错误发生在数据段,就标记数据段。
  • 重点:仲裁丢失不属于消极错误,所以这个字段填充0 00000,代表【无标准消极错误】,这个字段无效。

六、【仲裁错误段表示】(独立字段,和消极错误分开)

专门用来记录仲裁丢失的位置,仲裁丢失是独立于消极错误的一类事件。 你的日志:丢失在位位:1含义:节点发送报文时,在仲裁段第 1bit发生仲裁丢失。 原理: CAN 发送时,发送节点一边发,一边采样总线电平回读对比。 本节点发出隐性电平 1,但是总线被其他节点拉成显性电平 0。 CAN 规则:0 优先级高于 1,本节点输掉仲裁,立刻停止发送报文,TEC 计数增加。 你这个场景:STM32 和 USB-CAN 分析仪同一时刻同时发送报文,ID 仲裁冲突,在仲裁段第 1bit 输掉仲裁。

CAN周期报文设计

ID 分配

ID 分配实际上是在进行通信优先级设计

发送调度

实质上:管理“什么时候把哪些 CAN 报文交给 CAN 控制器发送”

抖动控制(jitter)

实际发送时间相对于理想时间存在变化

为什么会产生抖动:仲裁等等...

rolling counter

作用:让接收方知道报文是否连续到达,检测是否有丢帧、重复、乱序

checksum

含义:根据报文中的数据计算一个校验值,并把这个校验值也放进报文

为什么需要Checksum:不是 CRC 不好,是看安全等级、成本、算力、规范继承。低安全等级场景,Checksum 足够用,而且更简单、更快、更容易标准化,所以 AUTOSAR 专门保留了 E2E Profile1(RollCnt+Checksum)。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询