欢迎光临
我们一直在努力

现代智能汽车系统——CAN网络5

本文系统介绍了CAN总线的基础知识、报文设计、信号定义、多网络架构以及开发实践。主要内容包括:

  • CAN总线物理层特性(拓扑、电平、波特率)
  • 报文帧格式详解(标准帧/扩展帧结构)
  • 仲裁机制与错误检测方法
  • 报文ID设计策略与信号属性定义(起始位、长度、字节序等)
  • CAN Matrix设计方法(Excel与DBC文件)
  • 多CAN网络架构与网关路由设计
  • 开发工具与驱动实现(STM32示例)
  • 完整项目案例(电动车CAN网络设计)
  • 文章提供了8周系统学习路线,涵盖从基础到高级的CAN知识体系,并附有快速参考表与常见问题解答,适合汽车电子工程师系统学习CAN总线技术。

    CAN总线完整学习框架


    第一部分:CAN基础知识

    第一章:CAN总线概述

    1.1 什么是CAN?

    CAN(Controller Area Network,控制器局域网) 是由德国博世(Bosch)公司在1986年开发的一种串行通信协议,最初用于汽车内部电子控制单元(ECU)之间的通信。

    核心特点:

    • 🚗 多主机:任何节点都可以发起通信
    • 🔄 广播式:一个节点发送,所有节点接收
    • ⚡ 实时性强:基于优先级的仲裁机制
    • 🛡️ 可靠性高:强大的错误检测和处理机制
    • 💰 成本低:仅需双绞线,布线简单

    1.2 CAN总线的应用领域

    领域典型应用特点
    汽车 发动机控制、ABS、车身控制 最广泛应用
    工业 工厂自动化、机器人控制 抗干扰强
    医疗 医疗设备互联 高可靠性
    航空 飞行控制系统 安全关键
    新能源 电池管理系统(BMS) 实时性要求高

    1.3 CAN标准演进

    CAN 2.0A (1991) → 标准帧 (11位ID)
    CAN 2.0B (1995) → 扩展帧 (29位ID)
    CAN FD (2012) → 灵活数据速率
    CAN XL (2023) → 超长数据帧


    第二章:物理层基础

    2.1 总线拓扑

    线性总线结构:

    120Ω 120Ω
    终端电阻 │ │ 终端电阻
    │ │
    ─────┴──────┬──────┬──────┬──────┬─────────┴─────
    CAN_H │ │ │ │ CAN_H
    │ │ │ │
    CAN_L ─┘ ECU1 ECU2 ECU3 CAN_L

    最大节点数:理论无限,实际30-100个
    最大线长:取决于波特率

    2.2 电平与信号

    差分信号:CAN_H 和 CAN_L

    逻辑值名称CAN_H电压CAN_L电压差分电压
    0 显性(Dominant) 3.5V 1.5V 2.0V
    1 隐性(Recessive) 2.5V 2.5V 0V

    仲裁规则:显性覆盖隐性

    节点A发送:隐性(1)
    节点B发送:显性(0) ← 胜出
    总线实际:显性(0)

    2.3 波特率与距离

    波特率最大距离应用场景
    1 Mbps 40m 高速CAN(动力)
    500 Kbps 100m 高速CAN(底盘)
    250 Kbps 200m 中速CAN
    125 Kbps 500m 低速CAN(车身)

    速率与距离关系:

    • 速率越高 → 距离越短(信号衰减)
    • 距离越长 → 需要降低速率

    第三章:CAN报文帧格式

    3.1 CAN标准数据帧结构(重点)⭐⭐⭐⭐⭐

    完整帧结构图:

    ┌─────────────────────────────────────────────────────────────────┐
    │ CAN标准数据帧 (最多130位) │
    ├──────────┬─────────┬────────┬──────┬─────┬─────┬─────┬──────────┤
    │ 帧起始 SOF │ 仲裁场 │ 控制场 │ 数据场 │ CRC场│ ACK场│ EOF │ 帧间隔IFS │
    │ 1位 │ 12位 │ 6位 │ 0-64位│ 16位│ 2位│ 7位 │ 3位 │
    └──────────┴─────────┴────────┴──────┴─────┴─────┴─────┴──────────┘

    3.2 各字段详细解析

    字段1:帧起始(SOF – Start of Frame)
    • 长度:1位
    • 值:显性电平(0)
    • 作用:
      • 标志一帧的开始
      • 所有节点同步总线时钟
      • 唤醒处于空闲状态的节点
    字段2:仲裁场(Arbitration Field)

    标准格式共12位 = 11位ID + 1位RTR

    2.1 标识符(Identifier,11位)

    • 作用:决定报文优先级(数值越小,优先级越高)
    • 范围:0x000(最高优先级)~ 0x7FF(最低优先级)
    • 实例:

      ID = 0x123 (二进制: 00100100011)
      优先级高于 ID = 0x456

    常见汽车CAN ID分配:

    ID范围功能示例
    0x000-0x0FF 高优先级控制信号 发动机扭矩请求
    0x100-0x1FF 安全相关信号 ABS状态
    0x200-0x3FF 动力系统 发动机转速、车速
    0x400-0x5FF 车身控制 车门状态、灯光
    0x600-0x7FF 信息娱乐 多媒体控制

    2.2 RTR位(Remote Transmission Request)

    • 长度:1位
    • 值:
      • 0(显性):数据帧
      • 1(隐性):远程帧(请求数据)
    字段3:控制场(Control Field)

    共6位 = IDE(1) + r0(1) + DLC(4)

    3.1 IDE位(Identifier Extension)

    • 0:标准帧(11位ID)
    • 1:扩展帧(29位ID)

    3.2 r0位(保留位)

    • 值:必须为0(显性)
    • 作用:预留给未来协议扩展

    3.3 DLC(Data Length Code,数据长度码)

    • 长度:4位
    • 值:0-8
    • 作用:指示数据场字节数

    DLC二进制 十进制 数据字节数
    0000 0 0字节
    0001 1 1字节

    1000 8 8字节
    1001-1111 保留/非法

    注意:CAN FD可以支持更多字节(12/16/20/24/32/48/64字节)

    字段4:数据场(Data Field)
    • 长度:0-8字节(0-64位)
    • 作用:承载实际传输的数据
    • 字节顺序:通常采用大端序(Big-Endian)

    示例:发动机转速报文

    ID: 0x201
    DLC: 8
    数据: 0C 80 1F 40 00 00 00 00

    解析:
    字节0-1: 0C80 (大端) = 3200 RPM
    字节2-3: 1F40 (大端) = 8000 (节气门开度×100)
    字节4-7: 保留

    字段5:CRC场(Cyclic Redundancy Check)

    共16位 = CRC序列(15) + CRC界定符(1)

    5.1 CRC序列(15位)

    • 作用:错误检测
    • 计算:对SOF到数据场末尾的所有位进行CRC-15计算
    • 多项式:x^15 + x^14 + x^10 + x^8 + x^7 + x^4 + x^3 + 1

    5.2 CRC界定符(1位)

    • 值:1(隐性)
    • 作用:分隔CRC序列和ACK场

    错误检测能力:

    • ✅ 检测所有单比特错误
    • ✅ 检测所有双比特错误
    • ✅ 检测所有奇数个比特错误
    • ✅ 检测所有突发长度≤15的错误
    字段6:ACK场(Acknowledgment Field)

    共2位 = ACK槽(1) + ACK界定符(1)

    6.1 ACK槽(1位)

    • 发送节点:发送隐性位(1)
    • 接收节点:收到正确后,覆盖为显性位(0)
    • 作用:确认至少有一个节点正确接收

    工作原理:

    发送节点:发送隐性(1)

    接收节点:覆盖显性(0) ← 表示收到

    发送节点:检测到显性(0) → 发送成功

    6.2 ACK界定符(1位)

    • 值:1(隐性)
    • 作用:标志ACK场结束
    字段7:帧结束(EOF – End of Frame)
    • 长度:7位
    • 值:全为隐性(1111111)
    • 作用:标志一帧的结束
    字段8:帧间隔(IFS – Interframe Space)
    • 长度:3位(最少)
    • 值:全为隐性(111)
    • 作用:
      • 分隔连续的帧
      • 给节点处理时间
      • 错误节点在此期间不能发送

    3.3 扩展帧格式

    扩展帧ID(29位):

    • 结构:基本ID(11位) + SRR(1位) + IDE(1位) + 扩展ID(18位) + r1(1位)
    • 总ID范围:0x00000000 – 0x1FFFFFFF
    • 可用ID数量:536,870,912个
    • 应用:J1939协议、CANopen、现代汽车网络

    29位扩展ID结构(J1939为例):

    29位ID = 优先级(3) + 保留(1) + 数据页(1) + PDU格式(8) + PDU特定(8) + 源地址(8)

    示例:0x0CF00400
    二进制:00001100 11110000 00000100 00000000
    ───┬─── ──┬──┬── ──┬───── ──┬─────
    │ │ │ │ │
    优先级 R DP PF PS SA
    3 0 0 0xF0 0x04 0x00


    第四章:仲裁机制

    4.1 什么是仲裁?

    当多个节点同时发送时,CAN通过 非破坏性位仲裁 决定谁优先。

    4.2 仲裁过程

    规则:ID值越小,优先级越高

    示例:3个节点同时发送

    位序号: 10 9 8 7 6 5 4 3 2 1 0 RTR
    节点A: 0 0 1 0 0 1 0 0 0 1 1 0 (ID=0x123)
    节点B: 0 0 1 0 0 1 0 1 1 0 0 0 (ID=0x12C)
    节点C: 0 0 1 0 0 0 1 0 0 0 1 0 (ID=0x111)
    ↓ ↓ ↓ ↓ ↓ ↓
    总线实际: 0 0 1 0 0 0 …

    节点A、B检测到总线为0,但自己发送1
    退出竞争,停止发送

    结果:节点C胜出(ID=0x111最小)

    关键点:

  • 所有节点同时开始发送
  • 边发送边监听总线
  • 发现总线电平与自己不同(发1读到0)→ 立即停止
  • ID最小的节点获胜,继续发送
  • 失败节点自动重试
  • 4.3 优先级设计原则

    汽车CAN网络示例:

    0x001 – 发动机紧急停机请求 (最高优先级)
    0x100 – ABS激活信号
    0x200 – 发动机转速
    0x300 – 车速
    0x400 – 空调状态
    0x7FF – 诊断响应 (最低优先级)

    设计建议:

    • ✅ 安全关键信号 → 低ID
    • ✅ 实时性要求高 → 低ID
    • ✅ 信息类数据 → 高ID
    • ✅ 诊断数据 → 最高ID

    第五章:错误检测机制

    5.1 五种错误类型

    错误类型英文名称检测内容检测者
    位错误 Bit Error 发送位≠读取位 发送节点
    填充错误 Stuff Error 违反位填充规则 所有节点
    CRC错误 CRC Error CRC校验失败 接收节点
    格式错误 Form Error 固定位格式错误 所有节点
    应答错误 ACK Error 无节点应答 发送节点

    5.2 位填充(Bit Stuffing)

    规则:连续5个相同位后,自动插入1个相反位

    示例:

    原始数据: 1 1 1 1 1 0 0 0 0 0 0
    ↓插入 ↓插入
    填充后: 1 1 1 1 1 0 0 0 0 0 0 1

    解释:
    – 5个1后插入0
    – 6个0后插入1

    作用:

    • 保证足够的电平跳变
    • 便于时钟同步
    • 防止总线长时间保持同一电平

    应用范围:

    • ✅ SOF到CRC序列
    • ❌ CRC界定符到EOF(不填充)

    5.3 错误帧格式

    当节点检测到错误时,立即发送错误帧:

    ┌─────────────────────────────────┐
    │ 错误帧 │
    ├──────────────┬──────────────────┤
    │ 错误标志 │ 错误界定符 │
    │ 6-12位 │ 8位隐性 │
    └──────────────┴──────────────────┘

    错误标志:

    • 主动错误:6个连续显性位(违反位填充规则)
    • 被动错误:6个连续隐性位

    后果:

    • 当前帧被破坏
    • 所有节点丢弃该帧
    • 发送节点稍后自动重传

    5.4 错误计数与节点状态

    每个CAN节点维护两个计数器:

    发送错误计数器(TEC)

    • 发送失败 → +8
    • 发送成功 → -1

    接收错误计数器(REC)

    • 接收失败 → +1
    • 接收成功 → -1

    节点状态机:

    TEC≤127 && REC≤127
    ┌─────────────────────────┐
    │ 主动错误状态 │
    │ (Error Active) │
    └─────────────────────────┘

    TEC或REC >127

    ┌─────────────────────────┐
    │ 被动错误状态 │
    │ (Error Passive) │
    └─────────────────────────┘

    TEC >255

    ┌─────────────────────────┐
    │ 总线关闭状态 │
    │ (Bus Off) │
    └─────────────────────────┘

    状态说明:

    状态条件行为
    主动错误 TEC≤127 && REC≤127 正常工作,发送主动错误标志
    被动错误 TEC或REC >127 降级工作,发送被动错误标志
    总线关闭 TEC >255 断开总线,停止一切通信

    5.5 位定时

    位时间划分:

    ┌────┬────┬─────┬──────┐
    │同步段│传播段│相位段1│相位段2│
    │1TQ │1-8TQ│1-8TQ │1-8TQ │
    └────┴────┴─────┴──────┘
    ↑ 采样点

    TQ = Time Quantum(时间量子)

    典型配置(500Kbps):

    位时间 = 2μs
    TQ = 0.125μs
    1位 = 16TQ

    SS = 1TQ
    PTS = 2TQ
    PH1 = 5TQ
    PH2 = 8TQ
    采样点 = 50%


    第二部分:报文与信号设计

    第六章:报文ID设计

    6.1 ID的完整含义

    完整理解:

    ID = 网络标识 + 功能域标识 + 内容标识 + 优先级

    6.2 多CAN网络架构

    实际车辆中的多CAN网络:

    text

    整车CAN网络拓扑

    ├── 动力CAN (Powertrain CAN)
    │ ├── 波特率: 500 Kbps
    │ ├── 节点: ECM, TCM, BMS, MCU
    │ └── ID范围: 0x000-0x3FF

    ├── 底盘CAN (Chassis CAN)
    │ ├── 波特率: 500 Kbps
    │ ├── 节点: ABS, ESP, EPS
    │ └── ID范围: 0x000-0x3FF

    ├── 车身CAN (Body CAN)
    │ ├── 波特率: 125 Kbps
    │ ├── 节点: BCM, PEPS, 车门模块
    │ └── ID范围: 0x000-0x5FF

    ├── 座舱CAN (Cockpit CAN)
    │ ├── 波特率: 500 Kbps
    │ ├── 节点: IVI, IC, HUD, ADAS
    │ └── ID范围: 0x000-0x4FF

    └── 诊断CAN (Diagnostic CAN)
    ├── 波特率: 500 Kbps
    ├── 节点: 所有ECU
    └── ID范围: 0x700-0x7FF

    6.3 ID分配策略

    优先级导向分配:

    ID范围优先级典型应用周期
    0x000-0x0FF 最高 紧急制动、安全气囊 事件触发
    0x100-0x1FF 实时控制(ABS、ESP) 5-20ms
    0x200-0x3FF 中高 状态监控(转速、车速) 20-100ms
    0x400-0x6FF 中低 舒适功能(空调、车窗) 100-1000ms
    0x700-0x7FF 最低 诊断(OBD-II) 事件触发

    功能域分组示例:

    text

    动力CAN:
    0x100-0x1FF: BMS(电池管理)
    0x200-0x2FF: MCU(电机控制)
    0x300-0x3FF: VCU(整车控制)
    0x400-0x4FF: OBC/DCDC(充电/电源)

    车身CAN:
    0x100-0x1FF: BCM(车身控制)
    0x200-0x2FF: 车门/车窗
    0x300-0x3FF: 座椅
    0x400-0x4FF: 空调
    0x500-0x5FF: 灯光

    6.4 CAN网络标识方法

    方法一:通过报文属性标识(推荐)⭐⭐⭐⭐⭐

    在Excel Matrix中增加"CAN网络"列:

    报文ID(Hex)CAN网络网络缩写报文名称DLC周期(ms)发送者接收者网关路由ASIL
    0x100 Powertrain_CAN PT PT_BMS_1_Voltage 8 10 BMS VCU,MCU →Cockpit D
    0x101 Powertrain_CAN PT PT_BMS_2_SOC 8 100 BMS VCU →Cockpit B
    0x100 Body_CAN BODY BODY_BCM_1_Door 4 100 BCM IC →Cockpit(0x500) QM

    优点:

    • ✅ 直观清晰
    • ✅ 便于人工查看
    • ✅ 易于管理维护
    方法二:通过报文命名前缀(辅助方法)⭐⭐⭐⭐

    命名规范:

    text

    格式: [网络缩写]_[发送者]_[序号]_[功能描述]

    示例:
    PT_BMS_1_Voltage_Current (Powertrain CAN)
    PT_MCU_1_Motor_Status (Powertrain CAN)
    BODY_BCM_1_Door_Status (Body CAN)
    CHAS_ABS_1_Wheel_Speed (Chassis CAN)
    COCK_IC_1_Display_Request (Cockpit CAN)

    网络缩写标准:

    完整名称缩写说明
    Powertrain_CAN PT 动力总成
    Chassis_CAN CHAS 底盘
    Body_CAN BODY 车身
    Cockpit_CAN COCK 座舱
    Diagnostic_CAN DIAG 诊断

    第七章:报文属性定义

    7.1 报文核心属性列表

    完整报文定义表结构:

    字段名英文名数据类型示例说明
    报文ID(Hex) Message ID (Hex) 文本 0x100 十六进制表示
    报文ID(Dec) Message ID (Dec) 整数 256 十进制表示
    报文名称 Message Name 文本 BMS_1_Voltage_Current 唯一标识符
    CAN网络 CAN Network 枚举 Powertrain_CAN 所属物理CAN总线 ⭐
    网络缩写 Network Abbr 文本 PT_CAN 便于标识
    DLC Data Length Code 整数(0-8) 8 数据字节数
    周期(ms) Cycle Time (ms) 整数 10 发送周期,0表示事件触发
    发送类型 Send Type 枚举 Cyclic Cyclic/Event/Cyclic+Event
    发送者 Sender 文本 BMS 发送节点名称
    接收者 Receiver 文本列表 VCU,MCU,IC 逗号分隔
    跨网关转发 Gateway Routing 文本 →Cockpit_CAN 是否需要网关转发 ⭐
    ASIL等级 ASIL Level 枚举 ASIL-D QM/A/B/C/D
    安全机制 Safety Mechanism 文本 CRC+Counter CRC/Rolling Counter/E2E
    启动延迟(ms) Start Delay 整数 0 上电后首次发送延迟
    超时时间(ms) Timeout 整数 50 接收超时判定时间
    信号数量 Signal Count 整数 4 包含的信号个数
    描述 Description 文本 电池组核心数据 功能说明

    7.2 DLC(数据长度码)

    定义: 报文数据场的字节数

    取值范围:

    text

    CAN 2.0: 0-8 字节
    CAN FD: 0-8, 12, 16, 20, 24, 32, 48, 64 字节

    DLC编码(CAN FD):
    0-8: 实际字节数
    9: 12字节
    10: 16字节
    11: 20字节
    12: 24字节
    13: 32字节
    14: 48字节
    15: 64字节

    设计原则:

    text

    ✅ 够用即可,避免浪费
    ✅ 考虑未来扩展,预留1-2字节
    ❌ 不要为了"好看"统一用8字节

    7.3 周期(Cycle Time)

    定义: 报文发送的时间间隔,单位:毫秒(ms)

    典型值:

    text

    实时控制回路: 5-20ms (如电机控制、制动)
    状态监控: 50-100ms (如温度、压力)
    慢速状态: 500-1000ms (如门窗状态)
    事件触发: 0 (按需发送)

    设计原则:

    text

    安全相关: ≤20ms
    实时性要求高: ≤50ms
    一般状态信息: 100-500ms
    慢变量: ≥1000ms

    公式:
    周期 ≤ 1/(2×最快变化频率) [奈奎斯特采样定理]

    7.4 发送类型(Send Type)

    类型英文说明适用场景
    周期发送 Cyclic 固定周期持续发送 状态监控、实时控制
    事件触发 Event 事件发生时发送 故障报警、用户操作
    周期+事件 Cyclic + Event 周期发送+变化时立即发送 重要状态(如档位)

    示例:

    text

    周期发送 (Cyclic):
    – 电池电压:每10ms发送
    – 车速:每20ms发送

    事件触发 (Event):
    – 故障码:故障发生时立即发送
    – 诊断响应:收到请求后发送

    周期+事件 (Cyclic + Event):
    – 档位信号:
    * 正常:100ms周期发送
    * 档位切换时:立即发送

    7.5 ASIL等级

    定义: Automotive Safety Integrity Level (汽车安全完整性等级),来自ISO 26262标准

    等级划分:

    等级风险等级典型应用要求
    QM Quality Management 非安全相关 信息娱乐、舒适功能
    ASIL-A 最低 辅助功能 后视镜、雨刷
    ASIL-B 次要安全 SOC显示、灯光控制
    ASIL-C 重要安全 车速、档位
    ASIL-D 最高 关键安全 制动、转向、电池保护

    ASIL等级对Matrix的影响:

    text

    ASIL-D 报文要求:
    ✅ 必须有安全机制(CRC+AliveCounter或E2E)
    ✅ 周期≤20ms
    ✅ 超时监控≤3×周期
    ✅ 发送确认机制
    ✅ 完整的故障检测覆盖

    7.6 安全机制

    常用机制:

    机制说明开销ASIL适用性
    CRC 循环冗余校验 4-8位 B/C/D
    AliveCounter 滚动计数器 4位 B/C/D
    CRC+AliveCounter 组合 12位(1.5字节) C/D
    E2E Profile AUTOSAR端到端保护 根据配置 D

    E2E (End-to-End) 保护配置文件:

    text

    E2E Profile 01 (最常用):
    – CRC: 8位
    – Counter: 4位
    – DataID: 16位(隐含)
    开销:12位

    适用:ASIL-D,数据长度≤8字节

    字节布局示例:
    Byte0: [Counter(4bit)] [CRC(4bit高位)]
    Byte1: [CRC(4bit低位)] [Data…]


    第八章:信号定义

    8.1 信号属性全集

    完整信号定义表结构:

    类别属性说明示例
    位置 信号名称 唯一标识 Pack_Voltage
    所属报文ID 对应报文 0x100
    起始位(Start Bit) 0-63 0
    位长度(Bit Length) 1-64 16
    字节序(Byte Order) Intel/Motorola Intel
    数值 值类型(Value Type) Unsigned/Signed/Float Unsigned
    分辨率(Resolution) 原始值→物理值的乘数 0.1
    偏移量(Offset) 原始值→物理值的加数 0
    最小值/最大值 物理值范围 0 / 800
    单位(Unit) V/A/rpm/°C等 V
    初始值 上电默认值 0
    无效值 表示信号失效的值 0xFFFF
    安全 ASIL等级 继承或独立定义 ASIL-D
    其他 数据类型 C语言类型 uint16_t
    精度要求 测量精度 ±0.5%
    描述/备注 功能说明 电池组总电压

    物理值计算公式:

    text

    物理值 = 原始值 × 分辨率 + 偏移量

    Physical_Value = Raw_Value × Factor + Offset

    8.2 起始位(Start Bit / Offset)

    定义: 信号在报文数据场中的起始位位置

    Intel格式(小端,推荐):

    text

    Byte 0: Bit 7 6 5 4 3 2 1 0
    Byte 1: Bit 15 14 13 12 11 10 9 8
    Byte 2: Bit 23 22 21 20 19 18 17 16

    特点: 低字节在前,低位在右

    Motorola格式(大端):

    text

    Byte 0: Bit 0 1 2 3 4 5 6 7
    Byte 1: Bit 8 9 10 11 12 13 14 15

    特点: 高字节在前,高位在左

    设计建议:

    • ✅ 新项目统一用Intel
    • ✅ 信号尽量字节对齐(起始位=0,8,16,24…)
    • ✅ 同一报文内信号连续排列,无间隙
    • ❌ 避免不必要的跨字节信号

    8.3 位长度(Bit Length)

    常用长度:

    长度(bit)无符号范围有符号范围典型应用
    1 0-1 布尔值(开关状态)
    2 0-3 枚举(如档位P/R/N/D)
    4 0-15 -8~7 小范围枚举、计数器
    8 0-255 -128~127 百分比、温度
    16 0-65535 -32768~32767 电压、电流、转速
    32 0-4294967295 ±2147483648 里程、能量累计

    长度选择原则:

    text

    公式:
    所需位数 = ceil(log2((最大值-最小值)/分辨率 + 1))

    示例:电池电压
    范围:0-1000V
    分辨率:0.1V
    数据点数:(1000-0)/0.1 + 1 = 10001
    所需位数:log2(10001) = 13.29 → 14位

    但实际选择16位(2字节),原因:
    ✅ 字节对齐
    ✅ 有扩展余量
    ✅ 便于处理

    8.4 字节序(Byte Order)

    Intel (Little Endian,小端序):

    text

    特点:低字节存储在低地址

    示例:数值0x1234存储为
    内存地址: [低地址] [高地址]
    存储内容: 0x34 0x12

    优点:
    ✅ 现代处理器(x86/ARM)原生支持
    ✅ 主流车厂采用

    示例代码:
    uint16_t value = 0x1234;
    uint8_t data[2];
    memcpy(data, &value, 2);
    // data[0] = 0x34 (低字节)
    // data[1] = 0x12 (高字节)

    Motorola (Big Endian,大端序):

    text

    特点:高字节存储在低地址

    示例:数值0x1234存储为
    内存地址: [低地址] [高地址]
    存储内容: 0x12 0x34

    优点:
    ✅ 符合人类阅读习惯
    ✅ J1939等协议采用

    示例代码:
    uint16_t value = 0x1234;
    uint8_t data[2];
    data[0] = (value >> 8) & 0xFF; // 0x12
    data[1] = value & 0xFF; // 0x34

    选择建议:

    text

    新项目: 推荐Intel(主流)
    商用车(J1939): 必须Motorola
    混合网络: 禁止!必须统一

    8.5 值类型(Value Type)

    类型说明范围示例(16位)应用
    Unsigned 无符号整数 0-65535 电压、SOC、速度
    Signed 有符号整数 -32768~32767 电流、扭矩、温度
    IEEE Float 32位浮点数 ±3.4×10^38 高精度计算(少用)

    设计建议:

    text

    ✅ 优先使用Unsigned/Signed整数 + 因子/偏移
    原因:效率高、确定性好、便于调试

    ❌ 尽量避免浮点数
    原因:
    – 不同平台可能有差异
    – 无法直接用CAN工具查看
    – 效率低

    8.6 分辨率/因子(Resolution/Factor)

    定义: 原始值转换为物理值的乘数

    因子选择原则:

    text

    1. 精度够用即可
    车速:0.01 km/h
    电压:0.1 V

    2. 优先选择2的幂次(便于位运算)
    推荐:0.001, 0.125, 0.25, 0.5, 1, 2, 4, 8…
    避免:0.3, 0.7等(浮点运算误差)

    3. 参考行业惯例
    温度:1°C或0.1°C
    电压:0.1V或0.01V
    电流:0.1A
    转速:1rpm

    典型因子表:

    物理量推荐因子16位范围(无符号)说明
    电压 0.1 V 0-6553.5 V 覆盖高压电池
    电流 0.1 A 需配合偏移 见下文
    温度 1 °C 配合偏移-40 -40~215°C
    转速 1 rpm 0-65535 rpm 足够精度
    车速 0.01 km/h 0-655.35 km/h 高精度
    SOC 0.5 % 0-127.5 % 200个刻度

    8.7 偏移量(Offset)

    定义: 原始值转换为物理值的加数

    主要用途:

    text

    1. 支持负值范围
    原始值(无符号) + 偏移 → 物理值(可为负)

    2. 调整零点
    传感器输出不从0开始

    3. 扩展范围
    在有限位数下表示更大范围

    示例1:电池电流

    text

    需求:
    – 放电最大: 1000A (负值)
    – 充电最大: 500A (正值)
    – 精度: 0.1A

    优化方案(使用偏移):
    – 长度: 16位无符号
    – 因子: 0.1
    – 偏移: -1000
    – 原始值范围: 0~15000
    – 物理范围: -1000~500 A ✅

    计算:
    放电1000A: Raw = (-1000 – (-1000)) / 0.1 = 0
    充电500A: Raw = (500 – (-1000)) / 0.1 = 15000

    示例2:温度

    text

    需求:覆盖 -40°C ~ 215°C

    方案:
    – 长度: 8位无符号
    – 因子: 1
    – 偏移: -40
    – 原始值: 0~255
    – 物理范围: -40~215°C ✅

    计算:
    -40°C: Raw = (-40 – (-40)) / 1 = 0
    25°C: Raw = (25 – (-40)) / 1 = 65
    215°C: Raw = (215 – (-40)) / 1 = 255

    8.8 最小值/最大值

    定义: 信号的物理值有效范围

    设计原则:

    text

    理论最大值 = ((2^BitLength – 1) × Factor) + Offset

    但定义的最大值可以 ≤ 理论最大值

    原因:
    – 物理限制
    – 安全考虑
    – 传感器量程

    示例:

    text

    信号:Pack_Voltage
    – 长度: 16位
    – 因子: 0.1
    – 偏移: 0
    – 值类型: 无符号

    理论范围:
    最大 = (2^16 – 1) × 0.1 + 0 = 6553.5 V

    定义范围:
    最小值: 0 V
    最大值: 800 V (实际系统额定750V,留余量)

    无效值: 0xFFFF (6553.5 V) → 超出定义范围,表示信号无效

    8.9 单位(Unit)

    标准单位表:

    物理量SI单位常用单位备注
    电压 V V, mV, kV 高压用kV
    电流 A A, mA
    功率 W W, kW 电机功率用kW
    能量 J kWh, Wh 电池容量用kWh
    温度 K °C 汽车行业用°C
    速度 m/s km/h, mph 汽车用km/h
    转速 rad/s rpm 电机用rpm
    扭矩 Nm Nm
    压力 Pa bar, psi, kPa 轮胎用bar
    百分比 % % SOC、开度等

    8.10 初始值(Initial Value)

    定义: ECU上电或报文首次发送时的默认值

    设计原则:

    text

    1. 选择安全状态
    制动踏板:0% (未踩)
    加速踏板:0% (未踩)

    2. 选择合理状态
    SOC:50% (避免过充/过放报警)
    温度:25°C (常温)

    3. 避免触发故障
    不要选择会触发报警的值


    第三部分:CAN Matrix设计

    第九章:CAN Matrix概述

    9.1 什么是CAN Matrix?

    定义:

    text

    CAN Matrix = 完整的CAN网络描述文档
    包含: 节点 + 报文 + 信号 + 关系

    三层结构:

    text

    CAN网络
    ├── 节点层(Nodes)
    │ ├── ECU1, ECU2, ECU3…

    ├── 报文层(Messages)
    │ ├── Message1 (ID, 周期, 发送者, CAN网络)
    │ └── Message2

    └── 信号层(Signals)
    ├── Signal1 (起始位, 长度, 因子…)
    └── Signal2

    9.2 Matrix表现形式

    形式格式用途推荐度
    DBC文件 .dbc 工具自动化 ⭐⭐⭐⭐⭐
    Excel表格 .xlsx 人工编辑评审 ⭐⭐⭐⭐⭐
    ARXML .arxml AUTOSAR项目 ⭐⭐⭐⭐

    最常用组合:Excel(沟通) + DBC(工具)


    第十章:Excel Matrix设计

    10.1 完整Excel结构

    推荐的Sheet划分:

    • Sheet 1: 网络配置

      • 项目信息、版本、日期
      • CAN网络列表及参数
      • 节点统计、报文统计
    • Sheet 2: 节点列表 (Node List)

      • 节点名称、缩写、功能描述
      • 硬件版本、软件版本、供应商
    • Sheet 3: 报文列表 (Message List)

      • 报文ID、名称、CAN网络
      • DLC、周期、发送者、接收者
      • 网关路由、ASIL等级
    • Sheet 4: 信号定义 (Signal Definition)

      • 信号名称、所属报文、CAN网络
      • 起始位、长度、字节序
      • 分辨率、偏移、范围、单位
    • Sheet 5: 枚举值定义 (Value Tables)

      • 信号名称、值、含义
    • Sheet 6: 总线负载分析

      • 按报文计算负载
      • 按网络汇总负载
    • Sheet 7: 通信矩阵图

      • 节点间通信关系
      • 跨网络通信标注
    • Sheet 8: 修订历史

      • 版本、日期、修改人、修改内容

    10.2 Sheet 1: 网络配置

    text

    ┌────────────────────────────────────────────────────┐
    │ 项目名称: XX电动汽车CAN网络 │
    │ 版本: V1.2 │
    │ 日期: 2025-01-15 │
    │ 作者: 系统工程师 │
    │────────────────────────────────────────────────────│
    │ CAN网络列表: │
    │ 1. Powertrain CAN – 500 Kbps – 采样点87.5% │
    │ 2. Chassis CAN – 500 Kbps – 采样点87.5% │
    │ 3. Body CAN – 125 Kbps – 采样点75% │
    │ 4. Cockpit CAN – 500 Kbps – 采样点87.5% │
    │────────────────────────────────────────────────────│
    │ 统计信息: │
    │ – 节点总数: 12 │
    │ – 报文总数: 85 │
    │ – 信号总数: 456 │
    │ – 最高总线负载: 38.5% (Powertrain CAN) │
    └────────────────────────────────────────────────────┘

    10.3 Sheet 2: 节点列表

    #节点名称缩写功能描述所属CAN网络硬件版本软件版本供应商
    1 Vehicle_Control_Unit VCU 整车控制器 PT_CAN, BODY_CAN HW1.0 SW2.3 自研
    2 Battery_Management_System BMS 电池管理系统 PT_CAN HW2.1 SW3.5 CATL
    3 Motor_Control_Unit MCU 电机控制器 PT_CAN HW1.5 SW2.0 Huichuan
    4 Body_Control_Module BCM 车身控制模块 BODY_CAN HW3.0 SW2.1 Continental
    5 Instrument_Cluster IC 仪表盘 COCK_CAN HW3.0 SW4.1 Visteon
    6 ABS_System ABS 防抱死系统 CHAS_CAN HW2.0 SW3.0 Bosch

    10.4 Sheet 3: 报文列表(完整版)

    报文IDCAN网络网络缩写报文名称DLC周期发送者接收者网关路由ASIL安全机制超时描述
    0x100 Powertrain PT PT_BMS_1_Voltage 8 10 BMS VCU,MCU →Cockpit D CRC+Counter 30 电池电压电流
    0x101 Powertrain PT PT_BMS_2_SOC 8 100 BMS VCU →Cockpit B Counter 300 电池SOC
    0x200 Powertrain PT PT_MCU_1_Status 8 10 MCU VCU →Cockpit D E2E_P01 30 电机状态
    0x100 Body BODY BODY_BCM_1_Door 4 100 BCM IC →Cockpit(0x500) QM None 300 车门状态
    0x200 Body BODY BODY_PEPS_1_Key 4 100 PEPS BCM,VCU →PT(0x600) B Counter 300 钥匙状态
    0x100 Cockpit COCK COCK_IC_1_Display 8 50 IC IVI No QM None 显示请求

    关键列说明:

    • CAN网络:完整网络名称
    • 网络缩写:用于报文命名
    • 网关路由:
      • "No" = 不转发
      • "→Cockpit" = 转发到座舱CAN,ID不变
      • "→Cockpit(0x500)" = 转发到座舱CAN,ID映射为0x500

    10.5 Sheet 4: 信号定义(完整版)

    信号名称所属报文IDCAN网络报文名称起始位位长度字节序值类型分辨率偏移最小值最大值单位初始值无效值ASIL数据类型描述
    Pack_Voltage 0x100 PT PT_BMS_1_Voltage 0 16 Intel Unsigned 0.1 0 0 800 V 0 0xFFFF D uint16_t 电池组总电压
    Pack_Current 0x100 PT PT_BMS_1_Voltage 16 16 Intel Signed 0.1 -1000 -1000 1000 A 0 0x8000 D int16_t 电池组总电流
    SOC 0x101 PT PT_BMS_2_SOC 0 8 Intel Unsigned 0.5 0 0 100 % 50 0xFF B uint8_t 电池荷电状态
    Motor_Speed 0x200 PT PT_MCU_1_Status 0 16 Intel Signed 1 -10000 -10000 55535 rpm 0 0x8000 D int16_t 电机转速
    FL_Door_Status 0x100 BODY BODY_BCM_1_Door 0 2 Intel Unsigned 1 0 0 3 0 3 QM uint8_t 左前门状态

    10.6 Sheet 6: 总线负载分析

    CAN网络报文ID报文名称DLC周期(ms)帧长(bit)帧/秒位/秒负载(%)累计负载(%)
    PT_CAN 0x100 BMS_Voltage 8 10 130 100 13,000 2.6% 2.6%
    PT_CAN 0x101 BMS_SOC 8 100 130 10 1,300 0.26% 2.86%
    PT_CAN 0x200 MCU_Status 8 10 130 100 13,000 2.6% 5.46%
    PT_CAN小计 3850 192,500 38.5%
    BODY_CAN 0x100 BCM_Door 4 100 94 10 940 0.75% 0.75%
    BODY_CAN小计 580 9,400 7.5%

    负载计算公式:

    text

    单帧长度 = (47 + DLC×8) × 1.2 // 含20%位填充

    帧/秒 = 1000 / 周期(ms)

    位/秒 = 单帧长度 × 帧/秒

    负载(%) = 位/秒 / 波特率 × 100%


    第十一章:DBC文件详解

    11.1 DBC文件结构

    为每个CAN网络创建独立的DBC文件:

    text

    项目目录结构:
    ├── Powertrain_CAN.dbc
    ├── Chassis_CAN.dbc
    ├── Body_CAN.dbc
    ├── Cockpit_CAN.dbc
    └── Gateway_Routing.txt (网关路由表)

    11.2 DBC核心语法

    基本结构:

    dbc

    VERSION ""

    NS_ :
    NS_DESC_
    CM_
    BA_DEF_

    BS_:

    BU_: 节点1 节点2 节点3

    BO_ 报文ID 报文名称: DLC 发送节点
    SG_ 信号名 : 起始位|长度@字节序符号 (因子,偏移) [最小|最大] "单位" 接收节点

    CM_ BO_ 报文ID "报文注释";
    CM_ SG_ 报文ID 信号名 "信号注释";

    BA_DEF_ BO_ "GenMsgCycleTime" INT 0 10000;
    BA_ "GenMsgCycleTime" BO_ 报文ID 周期值;

    11.3 完整DBC示例(Powertrain_CAN.dbc)

    dbc

    VERSION ""

    NS_ :
    NS_DESC_
    CM_
    BA_DEF_
    BA_
    VAL_
    CAT_DEF_
    CAT_
    FILTER
    BA_DEF_DEF_
    EV_DATA_
    ENVVAR_DATA_
    SGTYPE_
    SGTYPE_VAL_
    BA_DEF_SGTYPE_
    BA_SGTYPE_
    SIG_TYPE_REF_
    VAL_TABLE_
    SIG_GROUP_
    SIG_VALTYPE_
    SIGTYPE_VALTYPE_
    BO_TX_BU_
    BA_DEF_REL_
    BA_REL_
    BA_SGTYPE_REL_
    SG_MUL_VAL_

    BS_:

    BU_: VCU BMS MCU OBC DCDC

    VAL_TABLE_ Charge_Status 0 "Not_Charging" 1 "Charging" 2 "Complete" 3 "Fault" ;

    BO_ 256 PT_BMS_1_Voltage_Current: 8 BMS
    SG_ AliveCounter : 0|4@1+ (1,0) [0|15] "" VCU,MCU
    SG_ CRC : 8|8@1+ (1,0) [0|255] "" VCU,MCU
    SG_ Pack_Voltage : 16|16@1+ (0.1,0) [0|800] "V" VCU,MCU
    SG_ Pack_Current : 32|16@1- (0.1,-1000) [-1000|1000] "A" VCU,MCU
    SG_ Max_Cell_Voltage : 48|16@1+ (0.001,0) [0|5] "V" VCU

    BO_ 257 PT_BMS_2_SOC_SOH: 8 BMS
    SG_ SOC : 0|8@1+ (0.5,0) [0|100] "%" VCU
    SG_ SOH : 8|8@1+ (0.5,0) [0|100] "%" VCU
    SG_ Charge_Status : 16|2@1+ (1,0) [0|3] "" VCU
    SG_ Fault_Level : 18|2@1+ (1,0) [0|3] "" VCU

    BO_ 512 PT_MCU_1_Motor_Status: 8 MCU
    SG_ Motor_Speed : 0|16@1- (1,-10000) [-10000|55535] "rpm" VCU
    SG_ Motor_Torque : 16|16@1- (0.1,-500) [-500|6053.5] "Nm" VCU
    SG_ Motor_Temp : 32|8@1+ (1,-40) [-40|215] "°C" VCU

    CM_ "Powertrain CAN Network – 动力CAN网络";

    CM_ BU_ BMS "电池管理系统 – Battery Management System";
    CM_ BU_ VCU "整车控制器 – Vehicle Control Unit";
    CM_ BU_ MCU "电机控制器 – Motor Control Unit";

    CM_ BO_ 256 "BMS核心数据,ASIL-D,10ms周期";
    CM_ BO_ 257 "BMS状态信息,ASIL-B,100ms周期";
    CM_ BO_ 512 "电机状态,ASIL-D,10ms周期";

    CM_ SG_ 256 Pack_Voltage "电池组总电压,无效值:0xFFFF";
    CM_ SG_ 256 Pack_Current "电池组总电流,负=放电,正=充电,无效值:0x8000";
    CM_ SG_ 257 Charge_Status "充电状态,见枚举表";

    BA_DEF_ "BusType" STRING ;
    BA_DEF_ "Baudrate" INT 0 1000000;
    BA_DEF_ BO_ "GenMsgCycleTime" INT 0 10000;
    BA_DEF_ BO_ "GenMsgSendType" ENUM "Cyclic","Event","CyclicAndEvent";
    BA_DEF_ BO_ "ASIL_Level" ENUM "QM","ASIL_A","ASIL_B","ASIL_C","ASIL_D";
    BA_DEF_ SG_ "GenSigStartValue" FLOAT 0 100000000000;

    BA_DEF_DEF_ "BusType" "CAN";
    BA_DEF_DEF_ "Baudrate" 500000;
    BA_DEF_DEF_ "GenMsgCycleTime" 0;
    BA_DEF_DEF_ "GenMsgSendType" "Cyclic";
    BA_DEF_DEF_ "ASIL_Level" "QM";
    BA_DEF_DEF_ "GenSigStartValue" 0;

    BA_ "BusType" "CAN";
    BA_ "Baudrate" 500000;

    BA_ "GenMsgCycleTime" BO_ 256 10;
    BA_ "GenMsgSendType" BO_ 256 "Cyclic";
    BA_ "ASIL_Level" BO_ 256 "ASIL_D";

    BA_ "GenMsgCycleTime" BO_ 257 100;
    BA_ "ASIL_Level" BO_ 257 "ASIL_B";

    BA_ "GenMsgCycleTime" BO_ 512 10;
    BA_ "ASIL_Level" BO_ 512 "ASIL_D";

    BA_ "GenSigStartValue" SG_ 257 SOC 50;
    BA_ "GenSigStartValue" SG_ 257 SOH 100;

    VAL_ 257 Charge_Status 0 "Not_Charging" 1 "Charging" 2 "Complete" 3 "Fault" ;
    VAL_ 257 Fault_Level 0 "Normal" 1 "Warning" 2 "Derate" 3 "Inhibit" ;

    11.4 DBC关键语法详解

    节点定义

    dbc

    BU_: 节点1 节点2 节点3

    示例:
    BU_: VCU BMS MCU IC

    报文定义

    dbc

    BO_ 报文ID 报文名称: DLC 发送节点

    示例:
    BO_ 256 BMS_Voltage: 8 BMS
    解释:ID=256(0x100), 名称=BMS_Voltage, 8字节, BMS发送

    信号定义

    dbc

    SG_ 信号名 : 起始位|长度@字节序符号 (因子,偏移) [最小|最大] "单位" 接收节点

    字节序符号:
    1 = Intel (小端)
    0 = Motorola (大端)

    符号:
    + = 无符号
    – = 有符号

    示例:
    SG_ Pack_Voltage : 16|16@1+ (0.1,0) [0|800] "V" VCU,MCU
    解释:
    – 起始位=16
    – 长度=16位
    – 字节序=Intel
    – 无符号
    – 因子=0.1,偏移=0
    – 范围=[0, 800]
    – 单位=V
    – 接收者=VCU和MCU


    第十二章:网关路由设计

    12.1 网关在多CAN网络中的作用

    网关功能:

    text

    ┌─────────────┐
    │ 中央网关 │
    │ Gateway │
    └──────┬──────┘

    ┌───┴───┬───────┬───────┐
    │ │ │ │
    PT_CAN BODY_CAN CHAS_CAN COCK_CAN

    功能:
    1. 报文路由转发
    2. ID映射(避免冲突)
    3. 协议转换
    4. 总线隔离
    5. 负载平衡

    12.2 网关路由表设计

    完整路由表(Gateway_Routing配置):

    源网络源ID报文名称目标网络目标ID转换规则优先级使能备注
    PT_CAN 0x100 BMS_Voltage COCK_CAN 0x100 直通 Yes 仪表显示
    PT_CAN 0x101 BMS_SOC COCK_CAN 0x101 直通 Yes 仪表显示
    PT_CAN 0x200 MCU_Status COCK_CAN 0x200 直通 Yes 仪表显示
    PT_CAN 0x300 VCU_Status BODY_CAN 0x300 直通 Yes 广播
    PT_CAN 0x300 VCU_Status COCK_CAN 0x300 直通 Yes 广播
    BODY_CAN 0x100 BCM_Door COCK_CAN 0x500 ID映射 Yes 避免冲突
    BODY_CAN 0x200 PEPS_Key PT_CAN 0x600 ID映射 Yes VCU需要
    COCK_CAN 0x400 ADAS_Warning PT_CAN 0x700 ID映射 Yes VCU响应

    转换规则说明:

    • 直通:ID不变,数据不变,直接转发
    • ID映射:更改目标ID(避免冲突),数据不变
    • 数据转换:ID和数据都可能变化(少用)

    12.3 网关软件实现

    C

    // 网关路由表定义
    typedef struct {
    CAN_Network_e src_network;
    uint32_t src_id;
    CAN_Network_e dst_network;
    uint32_t dst_id; // 如果与src_id不同,则进行ID映射
    bool enabled;
    } GW_RouteEntry_t;

    // 路由表
    const GW_RouteEntry_t g_gateway_routes[] = {
    // 源网络 源ID 目标网络 目标ID 使能
    {CAN_NETWORK_PT, 0x100, CAN_NETWORK_COCK, 0x100, true}, // 直通
    {CAN_NETWORK_PT, 0x101, CAN_NETWORK_COCK, 0x101, true}, // 直通
    {CAN_NETWORK_PT, 0x200, CAN_NETWORK_COCK, 0x200, true}, // 直通
    {CAN_NETWORK_BODY, 0x100, CAN_NETWORK_COCK, 0x500, true}, // ID映射!
    {CAN_NETWORK_BODY, 0x200, CAN_NETWORK_PT, 0x600, true}, // ID映射!
    {CAN_NETWORK_COCK, 0x400, CAN_NETWORK_PT, 0x700, true}, // ID映射!
    };

    #define ROUTE_TABLE_SIZE (sizeof(g_gateway_routes) / sizeof(GW_RouteEntry_t))

    /**
    * @brief 网关路由处理
    */
    void Gateway_Route(CAN_Network_e src_network, CAN_RxMessage_t *rx_msg) {
    for (int i = 0; i < ROUTE_TABLE_SIZE; i++) {
    GW_RouteEntry_t *route = &g_gateway_routes[i];

    // 匹配路由条目
    if (route->src_network == src_network &&
    route->src_id == rx_msg->id &&
    route->enabled) {

    // 转发到目标网络
    uint32_t tx_id = route->dst_id; // 可能是映射后的新ID

    CAN_Transmit(route->dst_network, tx_id, rx_msg->data, rx_msg->dlc);

    printf("[GATEWAY] Route: %s(0x%03X) -> %s(0x%03X)\\n",
    g_can_networks[src_network].name, rx_msg->id,
    g_can_networks[route->dst_network].name, tx_id);

    // 统计
    g_gateway_stats[i].routed_count++;
    }
    }
    }

    /**
    * @brief 网关主任务
    */
    void Gateway_Task(void) {
    CAN_RxMessage_t rx_msg;

    // 轮询所有CAN网络
    for (CAN_Network_e net = 0; net < CAN_NETWORK_MAX; net++) {
    if (CAN_Receive(net, &rx_msg) == 0) {
    // 接收成功,进行路由
    Gateway_Route(net, &rx_msg);
    }
    }
    }


    第四部分:高级应用

    第十三章:CAN FD

    13.1 CAN FD vs CAN 2.0

    特性CAN 2.0CAN FD
    数据场 0-8字节 0-64字节
    仲裁速率 1 Mbps 1 Mbps
    数据速率 1 Mbps 5-8 Mbps
    CRC 15位 17/21位
    帧开销 较大 相对较小
    兼容性 可与CAN 2.0混合组网

    13.2 CAN FD数据长度码(DLC)

    DLC值CAN 2.0字节数CAN FD字节数
    0-8 0-8 0-8
    9 保留 12
    10 保留 16
    11 保留 20
    12 保留 24
    13 保留 32
    14 保留 48
    15 保留 64

    13.3 CAN FD应用场景

    • ✅ 高清摄像头数据传输(ADAS)
    • ✅ 激光雷达点云数据
    • ✅ OTA软件升级
    • ✅ 高速诊断
    • ✅ 网关数据转发

    第十四章:诊断协议

    14.1 OBD-II / UDS ID分配

    text

    功能寻址:
    0x7DF – 广播请求(所有ECU)

    物理寻址(请求):
    0x7E0 – 发动机ECU
    0x7E1 – 变速箱ECU
    0x7E2 – ABS ECU

    物理寻址(响应):
    0x7E8 – 发动机响应 (0x7E0 + 0x08)
    0x7E9 – 变速箱响应

    14.2 示例:读取发动机转速

    text

    请求: 0x7E0: [02 01 0C 00 00 00 00 00]
    Byte0: 02 (后续字节数)
    Byte1: 01 (服务模式-当前数据)
    Byte2: 0C (PID-发动机转速)

    响应: 0x7E8: [04 41 0C 1F 40 00 00 00]
    Byte0: 04
    Byte1: 41 (0x40+0x01=肯定响应)
    Byte2: 0C (PID)
    Byte3-4: 1F 40

    转速 = (0x1F×256 + 0x40) / 4 = 2000 rpm


    第十五章:MCU-less架构

    15.1 概念

    去微控制器方案的核心思想:

    • 将原本散布在各边缘设备中的控制逻辑上收
    • 统一交由算力更强的区域控制器管理
    • 通过高速以太网或优化总线直接控制

    15.2 三种技术路线

    路线一:UART over CAN(TI, 英飞凌)
    • 低成本
    • 复用现有CAN物理层
    • 适合车灯等应用
    路线二:10BASE-T1S以太网(安森美, ADI)
    • 高性能
    • E2B硬件解析
    • 支持TSN同步
    路线三:CAN FD Light(ST)
    • 精简协议
    • 主从拓扑
    • 保留CAN稳健性

    15.3 优势

    • ✅ 降低BOM成本
    • ✅ 简化软件维护
    • ✅ 支持OTA升级
    • ✅ 软件定义硬件

    第五部分:软件开发

    第十六章:开发工具

    16.1 硬件工具

    工具价格特点推荐度
    PCAN-USB ¥500-2000 性价比高,支持CAN FD ⭐⭐⭐⭐⭐
    CANalyst-II ¥300 国产入门首选 ⭐⭐⭐⭐
    Kvaser Leaf ¥1000-5000 Linux支持好 ⭐⭐⭐⭐
    CANoe ¥5万+ 行业标准,功能最强 ⭐⭐⭐⭐⭐

    16.2 软件工具

    Windows:

    • PCAN-View (免费)
    • Busmaster (开源)
    • CANoe/CANalyzer (商业)

    Linux:

    Bash

    # 安装can-utils
    sudo apt install can-utils

    # 显示报文
    candump can0

    # 发送报文
    cansend can0 123#1122334455667788

    # 回放
    canplayer -I log.txt

    16.3 Python开发

    Python

    import can

    # 连接
    bus = can.interface.Bus(channel='can0', bustype='socketcan')

    # 发送
    msg = can.Message(
    arbitration_id=0x123,
    data=[0x11, 0x22, 0x33],
    is_extended_id=False
    )
    bus.send(msg)

    # 接收
    message = bus.recv()
    print(f"ID: {hex(message.arbitration_id)}, Data: {message.data.hex()}")


    第十七章:驱动开发

    17.1 STM32 HAL示例

    C

    // 初始化
    CAN_HandleTypeDef hcan;
    hcan.Instance = CAN1;
    hcan.Init.Mode = CAN_MODE_NORMAL;
    hcan.Init.Prescaler = 16;
    hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
    hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
    HAL_CAN_Init(&hcan);

    // 配置过滤器
    CAN_FilterTypeDef filter;
    filter.FilterIdHigh = 0x100 << 5;
    filter.FilterIdLow = 0;
    filter.FilterMaskIdHigh = 0x700 << 5;
    filter.FilterMaskIdLow = 0;
    filter.FilterMode = CAN_FILTERMODE_IDMASK;
    HAL_CAN_ConfigFilter(&hcan, &filter);

    // 发送
    CAN_TxHeaderTypeDef TxHeader;
    uint8_t TxData[8] = {0x11, 0x22, 0x33};
    uint32_t TxMailbox;

    TxHeader.StdId = 0x123;
    TxHeader.DLC = 3;
    TxHeader.IDE = CAN_ID_STD;
    TxHeader.RTR = CAN_RTR_DATA;
    HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox);

    // 接收
    CAN_RxHeaderTypeDef RxHeader;
    uint8_t RxData[8];
    HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData);

    17.2 多CAN网络管理

    C

    // CAN网络定义
    typedef enum {
    CAN_NETWORK_POWERTRAIN = 0,
    CAN_NETWORK_BODY = 1,
    CAN_NETWORK_COCKPIT = 2,
    CAN_NETWORK_MAX
    } CAN_Network_e;

    // 网络配置
    typedef struct {
    CAN_Network_e network_id;
    const char* name;
    uint32_t bitrate;
    CAN_HandleTypeDef* hcan;
    } CAN_NetworkConfig_t;

    // 全局配置
    const CAN_NetworkConfig_t g_can_networks[CAN_NETWORK_MAX] = {
    {CAN_NETWORK_POWERTRAIN, "PT_CAN", 500000, &hcan1},
    {CAN_NETWORK_BODY, "BODY_CAN", 125000, &hcan2},
    {CAN_NETWORK_COCKPIT, "COCK_CAN", 500000, &hcan3},
    };

    /**
    * @brief 发送CAN报文(指定网络)
    */
    int CAN_Transmit(CAN_Network_e network, uint32_t id, uint8_t *data, uint8_t dlc) {
    if (network >= CAN_NETWORK_MAX) {
    return -1;
    }

    CAN_HandleTypeDef *hcan = g_can_networks[network].hcan;

    CAN_TxHeaderTypeDef TxHeader;
    uint32_t TxMailbox;

    TxHeader.StdId = id;
    TxHeader.DLC = dlc;
    TxHeader.IDE = CAN_ID_STD;
    TxHeader.RTR = CAN_RTR_DATA;

    if (HAL_CAN_AddTxMessage(hcan, &TxHeader, data, &TxMailbox) != HAL_OK) {
    return -2;
    }

    printf("[TX] Network=%s, ID=0x%03X, DLC=%d\\n",
    g_can_networks[network].name, id, dlc);

    return 0;
    }


    第六部分:实战项目

    第十八章:完整项目案例

    18.1 项目背景

    项目:某纯电动乘用车CAN网络
    需求:

    • 节点:12个(VCU, BMS, MCU, OBC, DCDC, IC, AC, BCM, PEPS, ABS, ESP, GW)
    • CAN网络:4个(PT, BODY, CHAS, COCK)
    • 报文:85个
    • 波特率:500Kbps / 125Kbps
    • 目标总线负载:< 40%

    18.2 网络拓扑

    text

    ┌──────────────┐
    │ 中央网关GW │
    └──────┬───────┘

    ┌────────────────┼────────────────┬───────────┐
    │ │ │ │
    ┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐ ┌──▼────┐
    │动力CAN │ │车身CAN │ │座舱CAN │ │底盘CAN │
    │500 Kbps │ │125 Kbps │ │500 Kbps │ │500Kbps│
    └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └───┬───┘
    │ │ │ │
    ┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐ ┌───┴───┐
    │VCU │ │BCM │ │IC │ │ABS │
    │BMS │ │PEPS │ │IVI │ │ESP │
    │MCU │ │门控 │ │HUD │ │ │
    │OBC │ │座椅 │ │ADAS │ │ │
    │DCDC │ │空调 │ │ │ │ │
    └───────────┘ └───────────┘ └───────────┘ └───────┘

    18.3 关键报文设计

    BMS_1_Voltage_Current (0x100, PT_CAN, 10ms, ASIL-D)

    C

    // 报文结构
    typedef struct {
    uint8_t AliveCounter : 4;
    uint8_t Reserved : 4;
    uint8_t CRC;
    uint16_t Pack_Voltage; // 0.1V
    int16_t Pack_Current; // 0.1A, -1000偏移
    uint16_t Max_Cell_Voltage; // 0.001V
    } __attribute__((packed)) BMS_1_Msg_t;

    // 发送端(BMS)
    void BMS_Send_Voltage_Current(void) {
    static uint8_t counter = 0;
    uint8_t data[8];

    // 填充数据
    data[0] = counter & 0x0F;
    uint16_t voltage = (uint16_t)(pack_voltage / 0.1);
    data[2] = voltage & 0xFF;
    data[3] = (voltage >> 8) & 0xFF;

    int16_t current = (int16_t)((pack_current + 1000) / 0.1);
    data[4] = current & 0xFF;
    data[5] = (current >> 8) & 0xFF;

    uint16_t max_cell = (uint16_t)(max_cell_voltage / 0.001);
    data[6] = max_cell & 0xFF;
    data[7] = (max_cell >> 8) & 0xFF;

    // CRC
    data[1] = Calculate_CRC8(&data[2], 6);

    // 发送到动力CAN
    CAN_Transmit(CAN_NETWORK_POWERTRAIN, 0x100, data, 8);
    counter = (counter + 1) % 16;
    }

    // 接收端(VCU)
    bool VCU_Receive_BMS_Data(uint8_t *data) {
    static uint8_t last_counter = 0xFF;
    static uint32_t last_time = 0;

    // 超时检查
    if ((GetTime() – last_time) > 30) {
    Set_Fault(FAULT_BMS_TIMEOUT);
    return false;
    }

    // CRC校验
    if (Calculate_CRC8(&data[2], 6) != data[1]) {
    Set_Fault(FAULT_BMS_CRC);
    return false;
    }

    // Counter检查
    uint8_t counter = data[0] & 0x0F;
    if (counter != ((last_counter + 1) % 16) && last_counter != 0xFF) {
    Set_Warning(WARN_COUNTER_JUMP);
    }

    // 解析
    uint16_t raw_voltage = data[2] | (data[3] << 8);
    float voltage = raw_voltage * 0.1f;

    int16_t raw_current = data[4] | (data[5] << 8);
    float current = (raw_current * 0.1f) – 1000.0f;

    last_counter = counter;
    last_time = GetTime();
    return true;
    }

    18.4 总线负载计算

    Python

    def calculate_bus_load(messages, bitrate=500000):
    total_load = 0
    print(f"{'ID':<8} {'DLC':<5} {'周期':<8} {'帧/秒':<8} {'位/秒':<10} {'负载%':<8}")
    print("-" * 60)

    for msg_id, dlc, period in sorted(messages, key=lambda x: x[2]):
    frame_bits = (47 + dlc * 8) * 1.2
    frames_per_sec = 1000 / period
    bits_per_sec = frame_bits * frames_per_sec
    load = bits_per_sec / bitrate * 100
    total_load += load

    print(f"0x{msg_id:03X} {dlc:<5} {period:<8} {frames_per_sec:<8.0f} {bits_per_sec:<10.0f} {load:<8.2f}")

    print("-" * 60)
    print(f"总线负载: {total_load:.2f}%")

    if total_load < 40:
    print("✅ 负载正常")
    elif total_load < 60:
    print("⚠️ 负载偏高")
    else:
    print("❌ 负载过高")

    return total_load

    # 动力CAN报文
    pt_messages = [
    (0x100, 8, 10), # BMS核心数据
    (0x101, 8, 100), # BMS SOC
    (0x200, 8, 10), # MCU状态
    (0x300, 8, 20), # VCU状态
    # … 更多报文
    ]

    calculate_bus_load(pt_messages)


    第七部分:学习路线图

    第十九章:系统学习计划

    19.1 8周学习路线

    第1周:基础入门

    •  Day 1-2: CAN概述、物理层、电平信号
    •  Day 3-4: 掌握帧格式、仲裁机制
    •  Day 5-6: 理解错误检测、位定时
    •  Day 7: 总结+搭建测试环境

    第2周:报文与信号

    •  Day 1-2: 学习报文ID设计、属性定义
    •  Day 3-4: 掌握信号定义、编解码
    •  Day 5-6: 理解字节序、偏置计算
    •  Day 7: 手工计算报文练习

    第3周:多CAN网络

    •  Day 1-2: 学习多网络架构、网络标识
    •  Day 3-4: 掌握网关路由设计
    •  Day 5-6: 理解ID映射、协议转换
    •  Day 7: 网关软件实现

    第4周:Matrix设计

    •  Day 1-2: 学习Matrix概念、结构
    •  Day 3-4: 掌握Excel Matrix编写
    •  Day 5-6: 学习DBC文件语法
    •  Day 7: Excel ↔ DBC转换工具

    第5周:工具与开发

    •  Day 1-2: 安装配置硬件工具
    •  Day 3-4: 学习PCAN-View、Busmaster
    •  Day 5-6: Python can库编程
    •  Day 7: Linux can-utils实践

    第6周:驱动开发

    •  Day 1-3: STM32 HAL CAN驱动
    •  Day 4-5: 过滤器配置、中断处理
    •  Day 6-7: 完整收发程序

    第7周:高级应用

    •  Day 1-2: CAN FD学习
    •  Day 3-4: 诊断协议(OBD-II/UDS)
    •  Day 5-6: CANopen/J1939概览
    •  Day 7: MCU-less架构理解

    第8周:项目实战

    •  Day 1-5: BMS通信系统开发
    •  Day 6-7: CAN网关/负载分析工具

    19.2 能力检查清单

    初级 (1-2周)

    •  能解释CAN总线的基本原理
    •  能识别标准帧的各个字段
    •  理解仲裁机制
    •  会使用PCAN-View查看报文

    中级 (3-4周)

    •  能设计简单的CAN Matrix
    •  会编写DBC文件
    •  能手工计算信号的编解码
    •  会使用Python读写CAN
    •  理解多CAN网络架构

    高级 (5-8周)

    •  能独立设计完整的多CAN网络
    •  能开发CAN驱动程序
    •  能进行总线负载分析与优化
    •  能实现网关、诊断等高级功能

    专家级 (持续学习)

    •  精通AUTOSAR CAN协议栈
    •  能进行ISO 26262安全设计
    •  熟悉多种高级协议(CANopen/J1939)
    •  能指导团队完成复杂项目

    第八部分:附录

    附录A:快速参考表

    A.1 CAN报文帧结构速查

    text

    标准帧 (最多130位):
    ┌────┬────────┬──────┬──────┬─────┬─────┬─────┬────┐
    │SOF │仲裁场 │控制场│数据场│CRC场│ACK场│ EOF │IFS │
    │1位 │12位 │6位 │0-64位│16位 │2位 │7位 │3位 │
    └────┴────────┴──────┴──────┴─────┴─────┴─────┴────┘

    仲裁场 = ID(11位) + RTR(1位)
    控制场 = IDE(1) + r0(1) + DLC(4)
    CRC场 = CRC序列(15) + 界定符(1)
    ACK场 = ACK槽(1) + 界定符(1)

    A.2 常用波特率配置

    波特率位时间TQSSPTSPH1PH2采样点
    1 Mbps 1 μs 0.0625 μs 1 2 5 8 50%
    500 Kbps 2 μs 0.125 μs 1 2 5 8 50%
    250 Kbps 4 μs 0.25 μs 1 2 5 8 50%
    125 Kbps 8 μs 0.5 μs 1 2 5 8 50%

    A.3 常用数据类型范围

    类型位数无符号范围有符号范围
    bool 1 0-1
    uint8_t 8 0-255 -128~127
    uint16_t 16 0-65535 -32768~32767
    uint32_t 32 0-4294967295 ±2147483648

    A.4 典型分辨率选择

    物理量推荐分辨率位数范围
    电压 0.1 V 16 0-6553.5 V
    电流 0.1 A 16 + offset -1000~5553.5 A
    温度 1 °C 8 + offset -40~215 °C
    转速 1 rpm 16 0-65535 rpm
    车速 0.01 km/h 16 0-655.35 km/h
    SOC 0.5 % 8 0-127.5 %

    附录B:常见问题FAQ

    Q1:为什么CAN总线不需要地址?

    A: CAN采用广播机制,每个报文通过ID标识内容而非目标地址。所有节点都收到,根据需要过滤。

    Q2:同一ID可以存在于不同CAN网络吗?

    A:

    • ✅ 可以! 因为它们在不同的物理CAN总线上,互不干扰
    • ⚠️ 但需要在Matrix中明确标注CAN网络
    • ⚠️ 如果需要网关转发,可能需要ID映射

    Q3:如何选择Intel还是Motorola字节序?

    A:

    • Intel(小端):现代汽车OEM的主流,工具支持好
    • Motorola(大端):J1939等商用车协议
    • 建议:新项目统一用Intel

    Q4:报文周期如何选择?

    A:

    text

    安全关键: ≤20ms
    实时控制: ≤50ms
    状态监控: 100-500ms
    慢速信号: ≥1000ms

    公式: 周期 ≤ 1/(2×最快变化频率)

    Q5:总线负载多少算合理?

    A:

    text

    < 40%: 健康
    40-60%: 可接受,但需监控
    > 60%: 危险,必须优化
    > 80%: 紧急,系统将不稳定


    附录C:学习资源

    官方文档

    • ISO 11898-1: CAN协议标准
    • ISO 11898-2: 高速CAN物理层
    • CAN in Automation (CiA)官网

    书籍

    • 《CAN总线原理与应用技术》
    • 《Automotive Embedded Systems》
    • 《Understanding CAN》

    在线课程

    • Udemy: Automotive CAN Bus
    • Coursera: Automotive Networks

    开源项目

    • SocketCAN (Linux内核)
    • python-can
    • CANopen协议栈

    总结

    CAN总线学习的核心框架:

    text

    1. 基础 → 协议 → 报文 → 网络 → Matrix → 工具 → 项目
    ↓ ↓ ↓ ↓ ↓ ↓ ↓
    物理 帧格式 ID设计 多网络 DBC 编程 实战
    电平 仲裁 信号 路由 Excel 驱动 BMS/GW

    2. 关键要点
    – 掌握帧格式与仲裁
    – 理解报文与信号的完整属性
    – 重视多CAN网络标识与管理
    – 熟练使用Matrix工具(Excel+DBC)
    – 动手实践驱动与应用开发

    3. 学习建议
    – 理论与实践并重
    – 循序渐进,8周系统学习
    – 多做项目,积累经验
    – 关注新技术(CAN FD, 车载以太网)

    赞(0)
    未经允许不得转载:171主机测评 » 现代智能汽车系统——CAN网络5
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址