基于CCP协议的CAN总线

CCP通信协议:主从式,主设备通过CAN总线与多台从设备相连,主设备室测量标定系统 ,从设备是需要标定的ECU,主设备首先与其中一个从设备建立逻辑连接,主、从设备之间的所有的数据传递均由主机控制,从设备执行主设备命令后返回包含命令响应值或错误代码等信息的报文,同时从设备可以根据主设备通过控制命令设置的列表信息来定时地向主设备传送变量信息,数据的传递是由主设备初始化并且从设备来执行的,并且是由固定的循环采样频率或者事件触发的。

主设备通过USB-CAN接口与从设备连接,符合CAN2.0协议。

通信过程中,所有报文均为8个字节,包括命令、数据、数据长度、地址等信息

该通信协议参照CCP协议,可以与INCA等标定软件接口。

CAN通信:采用两个报文数据对象 CRO和DTO (命令接收对象)(命令发送对象)每个对象根据其数据流向,都有一个唯一的ID标示符进行标示,ID标识符可以由用户自己设定。

命令接收对象(CRO):

用于传递指令代码和内部功能码或主、从设备之间交换的存储区数据

 

 

表1

CMD (1 Byte):

命令代码。

CTR (1 Byte):

命令计数器。

Parameter and Data(6 Byte):

参数和数据场,命令相关的数据或参数

数据接收对象(DTO):

数据传输对象(DTO)指由从设备反馈的报文。DTO根据报文首字节PID的值可以由三种形式,见表2:

PID值

数据传输类型

备注

0xFF

CRM(Command Return Message)

由从设备发送,反馈CRO命令的报文

0xFE

Event Message

当从设备检测到内部发生错误机制时,由从设备自行向主设备发送,报告其当前的运行状态,并请求主设备暂停当前工作进程以处理发生的错误

0-0xFD

DAQ-DTO(Data Acquisition-DTO)

用于DAQ模式,由从设备定期向主设备发送。

根据对象描述表(ODT),确定需要上传的变量

 

 


       CRM-Event Message报文帧格式

表3:场说明

PID(1 Byte)

其值代表了DTO的类型

ERR(1 Byte)

命令返回错误代码

CTR(1 Byte)

命令计数器,与接收的相等。

Parameter and Data Field

参数和数据场,命令相关的数据或参数

 

(2). DAQ-DTO(Data Acquisition-DTO)的报文帧:

 


3. 协议命令列表及说明(标注绿色字体部分逐步补充完整)

3.1  命令列表:

命令名称

代码

说明

CONNECT

0x01

创建一个ECU的连接

SET_MTA

0x02

设置MTA地址

DNLOAD

0x03

下载最多5个字节数据到ECU

DNLOAD_6

0x23

下载6个字节数据到ECU

UPLOAD

0x04

从ECU上载最多5个字节数据

SHORT_UP

0x0F

从ECU上载最多5个数据(不用MTA)

DISCONNECT

0x07

断开到该ECU的连接

GET_DAQ_SIZE

0x14

得到指定DAQ列表大小

SET_DAQ_PTR

0x15

选中某指定DAQ列表中某ODT的某元素

WRITE_DAQ

0x16

设定该元素指定的地址

START_STOP

0x06

开始/停止采集指定的DAQ列表

EXCHANGE_ID

0x17

得到该ECU的标识符

GET_SEED

0x12

得到计算密钥的种子(SEED

UNLOCK

0x13

要求ECU释放某种功能

SET_S_STATUS

0x0C

设置当前会话状态

GET_S_STATUS

0x0D

得到当前会话状态

BUILD_CHKSUM

0x0E

计算指定区域的校验和

CLEAR_MEMORY

0x10

清除某内存区域

PROGRAM

0x18

FLASH编程(最多5个字节)

PROGRAM_6

0x22

FLASH编程(6个字节)

MOVE

0x19

从MTA0处拷贝指定长度的字节到MTA1处

TEST

0x05

测试当前在线的从设备

GET_ACTIVE_CAL_PAGE

0x09

得到当前标定页(RAM or FLASH

DIAG_SERVICE

0x20

 

ACTION_SERVICE

0x21

 

 

3.2命令返回错误代码

代码

描述

种类

状态改变

0x00

正确接收,无错误

0x01

DAQ处理器过载

0x10

命令处理器忙

0x11

DAQ处理器忙

。。。

待续

 

 

 

3.3命令详细说明

3.3.1CONNECT命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x01)

1

字节

命令计数器

2

站地址

4-7

字节

填0(不关心)

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

填0(不关心)

程序:connect命令

UINT8 Connect(UINT16 wStationAddr) {

        UINT8pbCROData[8];

       pbCROData[0] = CC_CONNECT;

       pbCROData[1] = m_bCTR ++;

        // intel format

        pbCROData[2] = (UINT8)(wStationAddr &0xFF);

       pbCROData[3] = (UINT8)(wStationAddr >> 8);

        // don't care

       pbCROData[4] = 0x00;

       pbCROData[5] = 0x00;

       pbCROData[6] = 0x00;

       pbCROData[7] = 0x00;

 

        UINT8bRlt;

        UINT8pbDTOData[8];

        if (CRC_OK != (bRlt = SendPackage(pbCROData,pbDTOData, TRANSMIT_TIMEOUT))) {

            return bRlt;

        }

       

        // Response

        // 0 Packet ID: 0xFF

        // 1 Command Return Code

        // 2 Command Counter = CTR

        // 3..7 don't care

        if (CRC_OK == pbDTOData[1]) {

           m_bConnected = TRUE;

        }

        return pbDTOData[1];

    }

3.3.2SET_MTA命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x02)

1

字节

命令计数器

2

字节

存贮器传输地址(MTA0,MTA1)

3

字节

地址扩展

4-7

无符号长整形

地址

数据传送对象(DTO):

0

字节

命令代码(0x01)

1

字节

命令计数器

2

站地址

4-7

字节

填0(不关心)

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

填0(不关心)

 

3.3.2SET_MTA命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x02)

1

字节

命令计数器

2

字节

存贮器传输地址(MTA0,MTA1)

3

字节

地址扩展

4-7

无符号长整形

地址

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

填0(不关心)

    UINT8SetMTA(UINT8 bMTANumber, UINT8 bAddrExt, UINT32 dwAddr) {

        UINT8pbCROData[8];

        pbCROData[0]= CC_SET_MTA;

       pbCROData[1] = m_bCTR ++;

       pbCROData[2] = bMTANumber;

       pbCROData[3] = bAddrExt;

       pbCROData[4] = (UINT8)(dwAddr >> 24);

       pbCROData[5] = (UINT8)(dwAddr >> 16);

       pbCROData[6] = (UINT8)(dwAddr >> 8);

       pbCROData[7] = (UINT8)(dwAddr >> 0);

       

        UINT8bRlt;

        UINT8pbDTOData[8];

       // if (CRC_OK != (bRlt = SendMessage(pbCROData, pbDTOData,TRANSMIT_TIMEOUT))) {

        if (CRC_OK != (bRlt = SendPackage(pbCROData,pbDTOData, 2000))) {

            return bRlt;

        }

        // Response

        // 0 Packet ID: 0xFF

        // 1 Command Return Code

        // 2 Command Counter = CTR

        // 3..7 don't care 

       

        return pbDTOData[1];

    }

 

3.3.3 DNLOAD命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x03)

1

字节

命令计数器

2

字节

需下传的数据长度

3-7

字节

数据

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3

字节

MTA0扩展位

4-7

字节

执行后MTA0地址(即地址加上长度)

   UINT8Download(UINT8 &bSize, PUINT8 pbData, UINT8 &bExtAddr, UINT32&dwAddr) {

        UINT8pbCROData[8];

        UINT8i;

       pbCROData[0] = CC_DNLOAD;

       pbCROData[1] = m_bCTR ++;

       pbCROData[2] = bSize;

        if ((NULL == pbData)) {

            return CRC_CMD_SYNTAX;

        }

        if (bSize > 5) {

           bSize = 5;

        }

        for (i = 0; i < bSize; i ++) {

           pbCROData[3 + i] = pbData[i];

        }

        for (; i < 5; i ++) {

           pbCROData[3 + i] = 0x00;

        }

       

        UINT8bRlt;

        UINT8pbDTOData[8];

        if (CRC_OK != (bRlt = SendPackage(pbCROData,pbDTOData, TRANSMIT_TIMEOUT))) {

            return bRlt;

        }

        // Response

        // 0 Packet ID: 0xFF

        // 1 Command Return Code

        // 2 Command Counter = CTR

        // 3 MTA0 extension (after post-increment)

        // 4..7 MTA0 address (after post-increment)

       bExtAddr = pbDTOData[3];

        dwAddr= (((UINT32)pbDTOData[4]) << 24) ||

           (((UINT32)pbDTOData[5]) << 16) ||

           (((UINT32)pbDTOData[6]) << 8) ||

           (((UINT32)pbDTOData[7]) << 0);

        return pbDTOData[1];

    }

 

 

3.3.4UPLOAD命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x04)

1

字节

命令计数器

2

字节

需上传的数据长度

3-7

字节

填0

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

上传的数据

UINT8 Upload(UINT8 &bSize, PUINT8 pbData) {

        UINT8pbCROData[8];

        UINT8i;

 

        if ((NULL == pbData)) {

            return CRC_CMD_SYNTAX;

        }

 

        if (bSize > 5) {

           bSize = 5;

        }

        pbCROData[0]= CC_UPLOAD;

       pbCROData[1] = m_bCTR ++;

       pbCROData[2] = bSize;

        // don't care

       pbCROData[3] = 0x00;

       pbCROData[4] = 0x00;

       pbCROData[5] = 0x00;

       pbCROData[6] = 0x00;

       pbCROData[7] = 0x00;

        

        UINT8bRlt;

        UINT8pbDTOData[8];

        if (CRC_OK != (bRlt = SendPackage(pbCROData,pbDTOData, TRANSMIT_TIMEOUT))) {

            return bRlt;

        }

        // Response

        // 0 Packet ID: 0xFF

        // 1 Command Return Code

        // 2 Command Counter = CTR

        // 3..7 requested data bytes

        for (i = 0; i < bSize; i ++) {

           pbData[i] = pbDTOData[3 + i];

        }

        return pbDTOData[1];

    }

   

 

 

3.3.5 SHORT UPLOAD命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x0F)

1

字节

命令计数器

2

字节

需上传的数据长度

3

字节

地址扩展

4-7

字节

地址

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

上传的数据

 

3.3.6DISCONNECT命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x07)

1

字节

命令计数器

2

字节

0x00 暂时断开, 0x01 断开

3

字节

不关心

4-5

字节

站地址(低位在前)

6-7

字节

填0(不关心)

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

填0(不关心)

UINT8 ShortUpload(UINT8 bSize, UINT8 bAddrExt, UINT32dwAddr, PUINT8 pbData) {

        UINT8pbCROData[8];

        UINT8i;

 

        if ((NULL == pbData)) {

            return CRC_CMD_SYNTAX;

        }

        if (bSize > 5) {

           bSize = 5;

        }

       pbCROData[0] = CC_SHORT_UPLOAD;

       pbCROData[1] = m_bCTR ++;

       pbCROData[2] = bSize;

       pbCROData[3] = bAddrExt;

       pbCROData[4] = (UINT8)(dwAddr >> 24);

       pbCROData[5] = (UINT8)(dwAddr >> 16);

       pbCROData[6] = (UINT8)(dwAddr >> 8);

       pbCROData[7] = (UINT8)(dwAddr >> 0);

       

        UINT8bRlt;

        UINT8pbDTOData[8];

        if(CRC_OK != (bRlt = SendPackage(pbCROData, pbDTOData, TRANSMIT_TIMEOUT))) {

            return bRlt;

        }

        // Response

        // 0 Packet ID: 0xFF

        // 1 Command Return Code

        // 2 Command Counter = CTR

        // 3..7 requested data bytes

        for (i = 0; i < bSize; i ++) {

           pbData[i] = pbDTOData[3 + i];

        }

        return pbDTOData[1];

    }

3.3.7GET_DAQ_SIZE命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x14)

1

字节

命令计数器

2

字节

DAQ表号(0,1…)

3

字节

填0(不关心)

4-7

字节

CAN 识别号(可选,暂不使用)

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3

字节

该DAQ列表中ODT的数目

4

字节

该列表中第一个ODT表PID值

5-7

字节

填0(不关心)

   UINT8pbCROData[8];

       pbCROData[0] = CC_GET_DAQ_SIZE;

       pbCROData[1] = m_bCTR ++;

       pbCROData[2] = bListNum;

        // don't care

        pbCROData[3]= 0x00;

       pbCROData[4] = (UINT8)(dwCANId >> 24);

       pbCROData[5] = (UINT8)(dwCANId >> 16);

       pbCROData[6] = (UINT8)(dwCANId >> 8);

       pbCROData[7] = (UINT8)(dwCANId >> 0);

       

        UINT8bRlt;

        UINT8pbDTOData[8];

        if (CRC_OK != (bRlt = SendPackage(pbCROData,pbDTOData, TRANSMIT_TIMEOUT))) {

            return bRlt;

        }

        // Response

        // 0 Packet ID: 0xFF

        // 1 Command Return Code

        // 2 Command Counter = CTR

        // 3 DAQ list size (= number of ODTs in this list)

        // 4 Fisrt PID of DAQ list

        // 5..7 don't care

       bDAQListSize = pbDTOData[3];

       bFirstPID = pbDTOData[4];

       

        return pbDTOData[1];

    }

 

 

 

 

 

 

 

 

3.3.8SET_DAQ_PTR命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x15)

1

字节

命令计数器

2

字节

DAQ表号(0,1…)

3

字节

QDT表号(0,1…)

4

字节

ODT表里的元素(0,1…)

5-7

字节

填0(不关心)

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

填0(不关心)

        UINT8pbCROData[8];

       pbCROData[0] = CC_SET_DAQ_PTR;

       pbCROData[1] = m_bCTR ++;

       pbCROData[2] = bListNum;

       pbCROData[3] = bODTNum;

       pbCROData[4] = bElementNum;

        pbCROData[5]= 0x00;

       pbCROData[6] = 0x00;

       pbCROData[7] = 0x00;

       

        UINT8bRlt;

        UINT8pbDTOData[8];

        if (CRC_OK != (bRlt = SendPackage(pbCROData,pbDTOData, TRANSMIT_TIMEOUT))) {

            return bRlt;

        }

        // Response

        // 0 Packet ID: 0xFF

        // 1 Command Return Code

        // 2 Command Counter = CTR

        // 3..7 don't care 

        return pbDTOData[1];

3.3.9WTITE_DAQ命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x16)

1

字节

命令计数器

2

字节

DAQ表中元素的长度(1,2,4)

3

字节

表中元素的扩展地址

4-7

字节

表中元素的地址

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

填0(不关心)

UINT8 pbCROData[8];

       pbCROData[0] = CC_WRITE_DAQ;

       pbCROData[1] = m_bCTR ++;

       pbCROData[2] = bElementSize;

       pbCROData[3] = bAddrExt;

       pbCROData[4] = (UINT8)(dwAddr >> 24);

       pbCROData[5] = (UINT8)(dwAddr >> 16);

       pbCROData[6] = (UINT8)(dwAddr >> 8);

       pbCROData[7] = (UINT8)(dwAddr >> 0);

       

        UINT8bRlt;

        UINT8pbDTOData[8];

        if (CRC_OK != (bRlt = SendPackage(pbCROData,pbDTOData, TRANSMIT_TIMEOUT))) {

            return bRlt;

        }

        // Response

        // 0 Packet ID: 0xFF

        // 1 Command Return Code

        // 2 Command Counter = CTR

        // 3..7 don't care 

        return pbDTOData[1];

3.3.10 START-STOP命令:

位(bit)

数据类型

描述

0

字节

命令代码(0x06)

1

字节

命令计数器

2

字节

停止:0x00;启动:0x01;准备:0x02

3

字节

DAQ 列表数

4

字节

该DAQ列表中最后一张ODT表数

5

字节

触发事件数

6-7

发送速率分频系数

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

填0(不关心)

 

UINT8 pbCROData[8];

       pbCROData[0] = CC_START_STOP;

       pbCROData[1] = m_bCTR ++;

       pbCROData[2] = bMode;

       pbCROData[3] = bDAQNum;

       pbCROData[4] = bLastODTNum;

       pbCROData[5] = bEventChannelNo;

       pbCROData[6] = (UINT8)(wTransmissionRatePrescaler >> 8);

       pbCROData[7] = (UINT8)(wTransmissionRatePrescaler >> 0);

       

        UINT8bRlt;

        UINT8pbDTOData[8];

        if (CRC_OK != (bRlt = SendPackage(pbCROData,pbDTOData, TRANSMIT_TIMEOUT))) {

            return bRlt;

        }

        // Response

        // 0 Packet ID: 0xFF

        // 1 Command Return Code

        // 2 Command Counter = CTR

        // 3..7 don't care 

        return pbDTOData[1];

 

 

 

 

 

 

 

 

 

3.3.11CLEAR_MEMORY命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x10)

1-7

字节

填0(不关心)

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

填0(不关心)

 

3.3.12PROGRAM命令:

命令接收对象(CRO):

位(bit)

数据类型

描述

0

字节

命令代码(0x18)

1-7

字节

填0(不关心)

数据传送对象(DTO):

位(bit)

数据类型

描述

0

字节

命令代码(0xFF)

1

字节

命令返回代码

2

字节

命令计数器

3-7

字节

填0(不关心)

 

4、标定实现(举例)

建立完善的匹配标定具体流程为:与底层ECU进行连接,监控、在线标定,上载和下载map图,断开连接等操作。对于匹配标定的2个最主要的任务,就是在线标定和实时监控,它是通过协议命令的组合,来实现的,下面举例说明如何实现:

4.1监控命令解析:(假设有n张DAQ列表,每张列表中有m张ODT表)

序号

上位机

CCP

CAN

备注

1

设置监控变量列表,选择采样速率

(.A2L)

2

GET_DAQ_SIZE

发送

重复n次

3

CRM-DTO

接收

重复n次

4

SET_DAQ_PTR

发送

list 0~list m-1

5

CRM-DTO

接收

list 0~list m-1

6

WRITE_DAQ

发送

list 0~list m-1

7

CRM-DTO

接收

list 0~list m-1

8

START_STOP

发送

list 0~list n-1

9

CRM-DTO

接收

list 0~list n-1

10

START_STOP_ALL

发送

开始监控

11

CRM-DTO

接收

12

DAQ-DTO

接收

接收多次

13

显示

解码显示

14

START_STOP_ALL

发送

停止显示

15

CRM-DTO

接收

 

4.2  在线标定

标号

上位机

CCP

CAN

备注

1

修改数据

可能有n次

2

SET_MTA

发送

3

CRM-DTO

接收

4

DNLOAD

发送

5

CRM-DTO

接收

6

SHORT_UP

发送

7

CRM-DTO

接收

 

 

 

SETMTA 命令:

    UINT8SetMTA(UINT8 bMTANumber, UINT8 bAddrExt, UINT32 dwAddr) {

        UINT8pbCROData[8];

        pbCROData[0]= CC_SET_MTA;

       pbCROData[1] = m_bCTR ++;

       pbCROData[2] = bMTANumber;

       pbCROData[3] = bAddrExt;

       pbCROData[4] = (UINT8)(dwAddr >> 24);

       pbCROData[5] = (UINT8)(dwAddr >> 16);

       pbCROData[6] = (UINT8)(dwAddr >> 8);

       pbCROData[7] = (UINT8)(dwAddr >> 0);

       

        UINT8bRlt;

        UINT8pbDTOData[8];

       // if (CRC_OK != (bRlt = SendMessage(pbCROData, pbDTOData,TRANSMIT_TIMEOUT))) {

        if (CRC_OK != (bRlt = SendPackage(pbCROData,pbDTOData, 2000))) {

            return bRlt;

        }

        // Response

        // 0 Packet ID: 0xFF

        // 1 Command Return Code

        // 2 Command Counter = CTR

        // 3..7 don't care 

       

        return pbDTOData[1];

    }

 

 

猜你喜欢

转载自blog.csdn.net/huan447882949/article/details/80234706