3. 测量基础
CCP协议,全称CAN Calibration Protocol。说白了,它就是ECU标定领域的事实标准。我最早接触CCP是在2008年,那时候还在用KWP2000做标定,后来转到CCP,第一感觉就是——这玩意儿真轻量。
CCP基于CAN总线,采用主从架构。一个标定工具(比如INCA、CANape)作为主设备,ECU作为从设备。主设备发命令,从设备响应。就这么简单。
CCP协议栈:分层看更清楚
CCP协议栈其实不复杂,我习惯把它分成三层来看:
| 层级 | 功能 | 我遇到过的坑 |
|---|---|---|
| 应用层 | 标定命令、DAQ/STIM控制 | 命令顺序搞错,ECU直接不响应 |
| 传输层 | CRO/DTO封装、分帧重组 | 8字节CAN帧不够用,要自己拼 |
| CAN驱动层 | CAN控制器初始化、收发 | 波特率不匹配,啥都白搭 |
应用层处理具体的标定命令,比如读内存、写内存、启动DAQ。传输层负责把命令打包成CRO和DTO。CAN驱动层就是最底层的收发。
主从设备通信机制:一问一答
CCP的通信模式很简单——主设备发CRO,从设备回DTO。CRO是Command Receive Object,DTO是Data Transmission Object。
每个CRO和DTO都是8字节的CAN数据帧。CRO的第一个字节是命令码,后面7个字节是参数。DTO的第一个字节是返回码(0xFF表示成功),后面是数据。
我曾经遇到过一个奇怪的问题:主设备发了CRO,从设备就是不回DTO。查了半天,发现是CANID配反了。CCP的CRO和DTO使用不同的CANID,接收ID和发送ID搞混,通信就断了。
CRO/DTO报文格式详解
CRO的格式,我直接给个例子:
// CRO报文格式(8字节)
Byte 0: 命令码 (如 0x01 = CONNECT)
Byte 1: 命令计数器 (CTR)
Byte 2-7: 命令参数
// 举个例子:CONNECT命令
// 命令码 0x01
// CTR = 0x00
// 参数 = 站点地址 (如 0x01)
// 完整CRO: 01 00 01 00 00 00 00 00
DTO的格式:
// DTO报文格式(8字节)
Byte 0: 返回码 (0xFF = 成功, 其他 = 错误码)
Byte 1: 错误码 (如果返回码不是0xFF)
Byte 2-7: 返回数据
// 成功响应例子
// 返回码 0xFF
// 数据 = 0x00 0x00 0x00 0x00 0x00 0x00
// 完整DTO: FF 00 00 00 00 00 00 00
命令计数器CTR很重要。每次主设备发CRO,CTR要递增。从设备在DTO里会回显这个CTR。如果CTR对不上,说明通信出问题了。
DAQ模式:自动上传数据
DAQ模式是CCP的精髓。它让ECU能自动、周期性地上传测量数据,不需要主设备一个一个命令去读。
我举个例子:你要采集发动机转速、水温、进气压力三个信号。如果用命令模式,每个周期要发3次读内存命令,CAN总线负载率直接飙升。用DAQ模式,ECU自己按设定周期发DTO,主设备只管收。
DAQ的配置流程:
- 定义ODT(Object Descriptor Table):每个ODT包含最多7个测量变量。
- 定义DAQ列表:一个DAQ列表包含多个ODT。
- 设置触发事件:比如每10ms触发一次。
- 启动DAQ:ECU开始自动发送DTO。
每个DAQ列表对应一个CANID。主设备通过不同的CANID区分不同的DAQ流。
STIM模式:批量写入标定数据
STIM模式和DAQ相反。DAQ是ECU往主设备发数据,STIM是主设备往ECU写数据。
STIM的典型应用场景:在线标定。你在标定工具上拖动一个MAP,新的标定数据通过STIM模式批量写入ECU的RAM里。
STIM的配置和DAQ类似:
- 定义STIM的ODT:指定要写入的变量。
- 定义STIM列表:和DAQ列表类似。
- 主设备发送STIM数据:通过特定的CANID发送。
- ECU接收并应用:ECU收到STIM数据后,更新到对应的内存地址。
STIM模式有个关键点——数据一致性。如果标定数据跨多个ODT,要保证所有ODT都更新完再应用。否则ECU可能处于不一致的状态。
CCP核心通信流程
下面这张图展示了CCP从连接到标定的完整流程:
这个流程我调试过无数次。最常出问题的是CONNECT这一步——站点地址不匹配。主设备发的站点地址和ECU里配置的不一样,ECU直接忽略CRO,不响应。
DAQ与STIM的对比
| 特性 | DAQ模式 | STIM模式 |
|---|---|---|
| 数据流向 | ECU → 主设备 | 主设备 → ECU |
| 典型用途 | 测量数据采集 | 在线标定写入 |
| 触发方式 | 周期/事件触发 | 主设备主动发送 |
| CANID数量 | 每个DAQ列表一个ID | 每个STIM列表一个ID |
| 数据量 | 大,持续上传 | 中等,按需写入 |
| 实时性要求 | 高,不能丢帧 | 中等,可重发 |
我个人的经验是:DAQ模式要特别注意CAN总线负载。一个DAQ列表如果配置了太多ODT,或者触发频率太高,CAN总线很容易被占满。我曾经在一个项目里,DAQ触发频率设成1ms,结果CAN总线负载率直接飙到80%,其他报文都发不出去了。
STIM模式则要注意写入时机。ECU在运行过程中,有些标定参数只能在特定状态下写入。比如喷油MAP,只能在发动机停机或怠速时写。如果在高转速时写,ECU可能直接进入保护模式。