本文属于DBC通讯解析的部分
1、DBC文件信号信息数据格式解读
每条报文消息里面有多个报文信号,报文信号的信息的起始标识为"SG_", 它以一个"BO_"开始至下一"BO_"之间的内容止,详细报文消息以缩进1或2个空格符形式类似树图子节点的方式呈现。
举例:一条消息下的一个信号的信息,此处缩进一个空格
SG_ EMS_SPEED : 0|13@1+ (1,0) [0|7000] “rpm” TCU
解释:
SG_ 代表一个信号信息的起始标识
EMS_SPEED 信号名
: 分割符号
0 信号起始bit
| 分割符号
13 信号总长度
@1+ @1表示是Intel格式(Motorola格式是0),+表示是无符号数据
(1,0) (精度值,偏移值)
[0|7000] [最小值|最大值], 物理意义的最小与最大,现实世界的有物理意义的值,比如此处发动机转速7000rpm
“rpm” “单位”
TCU 接收处理此信号的节点,同样可以不指明,写为Vector__XXX
CAN总线信号的编码格式有两种定义:Intel格式与Motorola格式,本文所列代码针对Motorola格式适用,是对《intel格式CAN报文 与 数值 互相转换C#》的补充
/// <summary>
/// Motorola格式CAN报文 转 数值
/// </summary>
/// <param name="data">CAN报文</param>
/// <param name="startBit">信号起始bit</param>
/// <param name="bitLength">信号总长度</param>
/// <param name="factor">精度值</param>
/// <param name="offset">偏移值</param>
/// <returns>物理信号值</returns>
public static double GetMotorolaSignalValue(byte[] data, int startBit, int bitLength, double factor, double offset)
{
ulong canSignalValue = 0;
for (int i = data.Length - 1, j = 0; i >= 0; i--, j++)
{
canSignalValue += (ulong)data[j] << i * 8;
}
int x = startBit / 8;
int y = startBit % 8;
int z = x * 8 + bitLength - y;
int rightMoveCount = data.Length * 8 - z;
canSignalValue >>= rightMoveCount;
canSignalValue = canSignalValue & ulong.MaxValue >> 64 - bitLength;
double values = canSignalValue * factor + offset;
return values;
}
/// <summary>
/// 数值 转 Motorola格式CAN报文
/// </summary>
/// <param name="MotorolaSignal">CAN报文</param>
/// <param name="values">物理信号值</param>
/// <param name="startBit">信号起始bit</param>
/// <param name="bitLength">信号总长度</param>
/// <param name="factor">精度值</param>
/// <param name="offset">偏移值</param>
/// <returns>Motorola格式CAN报文</returns>
public static byte[] ValueToMotorolaSignal_Part(byte[] MotorolaSignal, double values, int startBit, int bitLength, double factor, double offset)
{
// = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
ulong data = Convert.ToUInt64((values - offset) / factor);
int dataLength = bitLength / 8 + (bitLength / 4) % 2;
int str_length = data.ToString().Length;
int MotorolaSignal_pos = startBit / 8;
data = str_length % 2 != 0 ? data << 4 : data;
for (int Count = dataLength - 1; Count >= 0; Count--, MotorolaSignal_pos++)
{
ulong newBit = (data >> (8 * Count)) & 0xFF;
ulong newBit2 = ((newBit << 4) & 0xF0) + ((newBit >> 4) & 0x0F);
ulong Bit = (data>0x0F & bitLength>8) ? newBit2 : newBit;
MotorolaSignal[MotorolaSignal_pos] = Convert.ToByte(Bit);
}
return MotorolaSignal;
}