找回密码
 成为会员
查看: 4635|回复: 0

SAE-J1850汽车CAN总线CheckSum算法之CRC-8校验算法

[复制链接]

394

帖子

8

精华

5913

铜板

管理员

Rank: 9Rank: 9Rank: 9

积分
76387
发表于 2021-11-1 15:39:58 | 显示全部楼层 |阅读模式

We are leading you to the next level!

您需要 登录 才可以下载或查看,没有帐号?成为会员

x
CRC(Cyclic Redundancy Check),循环冗余校验

CRC算法将数据与多项式相除,得到的余数再与多项式相除,如此反复,所以叫循环冗余,最终得到一个和多项式位数相同的余数,作为校验码;

多项式决定了校验码的位数,根据校验码位数不同,一般有CRC-4,CRC-8,CRC-16,CRC-32,CRC-64,CRC-128等,不同的多项式对错误的检测率有差别,CRC相关标准中推荐的多项式都是精心挑选的。

SAE-J1850中的CRC-8校验算法

SAE-J1850中推荐的CRC校验多项式为1Dh, 即:x^8+x^4+x^3+x^2+1;

多项式的最高位默认均为1,且在CRC-8算法中,最高位不使用,因此在多项式记录时去掉了最高位;

1Dh转化为二进制为11101b,最高位补1后为10011101b,二进制中的每一位,对应多项式中的系数;

SAE-J1850中的CRC-8算法被AUTOSAR标准所引用,后者还推荐了另外一种多项式为2Fh(x^8+x^5+x^3+x^2+x^1+1)的CRC-8校验算法。

参见:https://www.autosar.org/fileadmin/user_upload/standards/classic/4-3/AUTOSAR_SWS_CRCLibrary.pdf

SAE-J1850中的CRC-8校验算法嵌入式代码实现(C语言)

u8 crc8(u8 *data, u8 length)                        //SAE-J1850 CRC-8 function
{
        u8 t_crc;
        u8 f, b;
        t_crc = 0xFF;
        for (f = 0; f < length; f++)
        {
                t_crc ^= data[f];
                for (b = 0; b < 8; b++)
                {
                        if ((t_crc & 0x80) != 0)                        //最高位为1,需要异或
                        {
                                t_crc <<= 1;
                                t_crc ^= 0x1D;
                        }
                        else
                        {
                                t_crc <<= 1;
                        }
                }
        }
        return ~t_crc;                        //按位非,相当于异或0xFF
}

上述0xFF、0x1D、0xFF分别对应SAE-J1850中规定的Polynomial、Initial value、XOR value,如下图所示:

Autosar_CRC-8_SAE_J1850

Autosar_CRC-8_SAE_J1850


在线验证CRC-8校验算法有效性

推荐一个可以在线运行C代码的网页:https://c.runoob.com/compile/11/

使用SAE-J1850中的示例,0x0F 0xAA 0x00 0x55,CRC为0x79;

验证代码如下:

#include <stdio.h>
typedef unsigned char u8;
u8 crc8(u8 *data, u8 length)
{
        u8 t_crc;
        u8 f, b;
        t_crc = 0xFF;
        for (f = 0; f < length; f++)
        {
                t_crc ^= data[f];
                for (b = 0; b < 8; b++)
                {
                        if ((t_crc & 0x80) != 0)
                        {
                                t_crc <<= 1;
                                t_crc ^= 0x1D;
                        }
                        else
                        {
                                t_crc <<= 1;
                        }
                }
        }
        return ~t_crc;
}
int main()
{
        u8 data[4]={0x0F, 0xAA, 0x00, 0x55};
        u8 length=4;
        u8 t_crc;
        t_crc=crc8(data,length);
        printf("\r\nCRC8=%02X\r\n", t_crc);
}
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

Archiver|手机版|AutoSim仿真教程 ( 皖ICP备15024617号-9 )

GMT+8, 2024-5-6 08:00 , Processed in 0.028868 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc. Design AutoSim

快速回复 返回顶部 返回列表