基于Simulink搭建dbc及checksum校验、roiling
1.dbc文件格式以及数据结构定义
CAN数据通信矩阵如下表所示。
|
Bit7 |
Bit6 |
Bit5 |
Bit4 |
Bit3 |
Bit2 |
Bit1 |
Bit0 | |
|
Byte0 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
|
Byte1 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
|
Byte2 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
|
Byte3 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
|
Byte4 |
39 |
38 |
37 |
36 |
35 |
34 |
33 |
32 |
|
Byte5 |
47 |
46 |
45 |
44 |
43 |
42 |
41 |
40 |
|
Byte6 |
55 |
54 |
53 |
52 |
51 |
50 |
49 |
48 |
|
Byte7 |
63 |
62 |
61 |
60 |
59 |
58 |
57 |
56 |
1.Intel格式
当一个信号的数据长度超过1 个字节(8 位)或者数据长度不超过一个字节但是采用跨字节方式实现时,该信号的高位(S_msb)将被放在高字节(MSB)的高位,信号的低位(S_lsb)将被放在低字节(LSB)的低位。
信号字节传输时低字节在前,高字节在后,信号的起始位为最低字节的最低位。
2.Motorola格式
当一个信号的数据长度超过 1 个字节(8 位)或者数据长度不超过一个字节但是采用跨字节方式实现时,该信号的高位(S_msb)将被放在低字节(MSB)的高位,信号的低位(S_lsb)将被放在高字节(LSB)的低位。这样,信号的起始位就是高字节的低位。
信号字节传输时高字节在前,低字节在后,信号的起始位为最低字节的最低位。
假设有一个dbc文件如下所示:

该信号的高位(S_msb)将被放在低字节(MSB)的高位,所以为摩托罗拉格式。
定义数据如下:
struct ID{
union {
uint16_t D;
//---------
struct {
uint16_t frontLeftTorque_lsb:8;//先定义的在低位
uint16_t frontLeftTorque_msb:8;
}bit;
}DATA01;
union {
uint16_t D;
//---------
struct {
uint16_t frontRightTorque_lsb:8;//先定义的在低位
uint16_t frontRightTorque_msb:8;
}bit;
}DATA23;
union {
uint16_t D;
//---------
struct {
uint16_t rearLeftTorque_lsb:8;//先定义的在低位
uint16_t rearLeftTorque_msb:8;
}bit;
}DATA45;
union {
uint16_t D;
//---------
struct {
uint16_t rearRightTorque_lsb:8;//先定义的在低位
uint16_t rearRightTorque_msb:8;
}bit;
}DATA67;
};
下发数据报文代码示例如下:
sendFrame.can_id = 0x...;//这样赋值默认标准帧
sendFrame.can_dlc = 8;//数据长度为 8个字节
sendFrame.data[0] = ID.DATA01.bit.frontLeftTorque_msb; //存放数据高位
sendFrame.data[1] = ID.DATA01.bit.frontLeftTorque_lsb; //存放数据低位
sendFrame.data[2] = 0x00;
sendFrame.data[3] = 0x00;
sendFrame.data[4] = ID.DATA45.bit.rearLeftTorque_msb;
sendFrame.data[5] = ID.DATA45.bit.rearLeftTorque_lsb;
sendFrame.data[6] = 0x00;
sendFrame.data[7] = 0x00;
int bytesSend = write(can_skt, &sendFrame, sizeof(sendFrame));
if(bytesSend != sizeof(sendFrame)){
printf("Send Error\n!");
}
2.基于simulink模块搭建RollingCounter以及CheckSum
1.例子报文

chesum检验公式:
校验和 = (字节1 + 字节2 + 字节3 + 字节4 + 字节5 +字节6 + 字节7 + 报文计数器 & 0x0F + 报文ID低字节+ 报文ID中低字节 + 报文ID中高字节 + 报文ID高字节)
校验和 = ((校验和 >> 4) + 校验和) & 0x0F
模块搭建如下:


其中,-15.687为偏移量,1/2048为分辨率。
心跳值模块搭建如下:

3.测试过程中的问题
在实际测试过程中,由于simulnik与C代码有差异性,在测试过程中发现Checksum与实际要下发的值少1,所以会导致checksum校验不对,无法发送完整的下发报文,因此需要严格遵守数据格式,确保数据下发的正确性。checksum发送错误如下:

校验和DA与下发的CA中,发送下去的checksum=C与实际的D少1。
更多推荐


所有评论(0)