找回密码
 成为会员
AutoSim仿真教程 门户 技术教程 查看内容

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

2021-11-1 15:49| 发布者: autosim| 查看: 2186| 评论: 0|原作者: autosim

摘要: CRC(Cyclic Redundancy Check),循环冗余校验 CRC算法将数据与多项式相除,得到的余数再与多项式相除,如此反复,所以叫循环冗余,最终得到一个和多项式位数相同的余数,作为校验码; 多项式决定了校验码的位数,根 ...
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

在线验证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, 2022-12-8 17:50 , Processed in 0.019747 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc. Design AutoSim

返回顶部