一、数据帧说明

  1. 间隔场低电平最少13个bit

  1. 同步场1个字节 0x55

  1. 标识场1个字节 PID (bit0-5:是实际PID,bit6-7是校验位)

  1. 数据场n+1个字节D0-Dn,LIN一帧数据最大可以传8个字节(n<=7)

  1. 校验场1个字节 Sum

二、PID与Sum计算

PID计算
/*
bit7 = ~(bit1 ^ bit3 ^ bit4 ^ bit5);
bit6 = (bit0 ^ bit1 ^ bit2 ^ bit4);
*/
//1.直接计算
union LIN_PID
{
    unsigned char PID;
    struct
    {
        unsigned char  bit0 : 1;
        unsigned char  bit1 : 1;
        unsigned char  bit2 : 1;
        unsigned char  bit3 : 1;
        unsigned char  bit4 : 1;
        unsigned char  bit5 : 1;
        unsigned char  bit6 : 1;
        unsigned char  bit7 : 1;
    }bit;
};

unsigned char GetPID(unsigned char PID)
{
    union LIN_PID Pid_data;
    Pid_data.PID = PID;
    Pid_data.bit.bit7 = ~(Pid_data.bit.bit1 ^ Pid_data.bit.bit3 ^ Pid_data.bit.bit4 ^ Pid_data.bit.bit5);
    Pid_data.bit.bit6 = (Pid_data.bit.bit0 ^ Pid_data.bit.bit1 ^ Pid_data.bit.bit2 ^ Pid_data.bit.bit4);
    return Pid_data.PID;
}

//2.PID数组表
/*******************************************
下面表是上面代码计算从0x00-0xFF对应的PID
for (i = 0; i < 256; i++)
{
    printf("0x%02x,", GetPID(i));
}
PID实际只有6位,即0x00-0x3F,多计算到0xFF,
是因为有的文档是给6bit PID,有的给8bit PID。
例如0x3D(6bit)=0x7D(8bit)即bPID[0x3D]=bPID[0x7D]
*******************************************/
const unsigned char bPID[] = {
0x80,0xc1,0x42,0x03,0xc4,0x85,0x06,0x47,0x08,0x49,0xca,0x8b,0x4c,0x0d,0x8e,0xcf,
0x50,0x11,0x92,0xd3,0x14,0x55,0xd6,0x97,0xd8,0x99,0x1a,0x5b,0x9c,0xdd,0x5e,0x1f,
0x20,0x61,0xe2,0xa3,0x64,0x25,0xa6,0xe7,0xa8,0xe9,0x6a,0x2b,0xec,0xad,0x2e,0x6f,
0xf0,0xb1,0x32,0x73,0xb4,0xf5,0x76,0x37,0x78,0x39,0xba,0xfb,0x3c,0x7d,0xfe,0xbf,
0x80,0xc1,0x42,0x03,0xc4,0x85,0x06,0x47,0x08,0x49,0xca,0x8b,0x4c,0x0d,0x8e,0xcf,
0x50,0x11,0x92,0xd3,0x14,0x55,0xd6,0x97,0xd8,0x99,0x1a,0x5b,0x9c,0xdd,0x5e,0x1f,
0x20,0x61,0xe2,0xa3,0x64,0x25,0xa6,0xe7,0xa8,0xe9,0x6a,0x2b,0xec,0xad,0x2e,0x6f,
0xf0,0xb1,0x32,0x73,0xb4,0xf5,0x76,0x37,0x78,0x39,0xba,0xfb,0x3c,0x7d,0xfe,0xbf,
0x80,0xc1,0x42,0x03,0xc4,0x85,0x06,0x47,0x08,0x49,0xca,0x8b,0x4c,0x0d,0x8e,0xcf,
0x50,0x11,0x92,0xd3,0x14,0x55,0xd6,0x97,0xd8,0x99,0x1a,0x5b,0x9c,0xdd,0x5e,0x1f,
0x20,0x61,0xe2,0xa3,0x64,0x25,0xa6,0xe7,0xa8,0xe9,0x6a,0x2b,0xec,0xad,0x2e,0x6f,
0xf0,0xb1,0x32,0x73,0xb4,0xf5,0x76,0x37,0x78,0x39,0xba,0xfb,0x3c,0x7d,0xfe,0xbf,
0x80,0xc1,0x42,0x03,0xc4,0x85,0x06,0x47,0x08,0x49,0xca,0x8b,0x4c,0x0d,0x8e,0xcf,
0x50,0x11,0x92,0xd3,0x14,0x55,0xd6,0x97,0xd8,0x99,0x1a,0x5b,0x9c,0xdd,0x5e,0x1f,
0x20,0x61,0xe2,0xa3,0x64,0x25,0xa6,0xe7,0xa8,0xe9,0x6a,0x2b,0xec,0xad,0x2e,0x6f,
0xf0,0xb1,0x32,0x73,0xb4,0xf5,0x76,0x37,0x78,0x39,0xba,0xfb,0x3c,0x7d,0xfe,0xbf
};
Sum计算

经典校验(Lin1.x、Lin2.x):pData只包含D0……Dn

增强校验(Lin2.x):pData包含PID、D0……Dn

注意:PID 0x3C、0x3D只用经典校验

unsigned char LIN_GetCheckSum(unsigned char* pData, int nSize)
{
    int i = 0;
    unsigned short wSum = 0;
    unsigned char bSum = 0;

    for (i = 0; i < nSize; i++)
    {
        wSum += pData[i];
        if (wSum > 255)
        {
            wSum -= 255;
        }
    }
    bSum = wSum & 0xff;    
    return (~bSum);
}

//测试D0=1,D1=2,D2=3,D3=4
int main()
{
    unsigned char bData[]={0x1,0x2,0x3,0x4};
    printf("0x%02x",LIN_GetCheckSum(bData, sizeof(bData)));
}

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐