CRC 应用实例

        CRC J1850算法,网上有很多教程,大多都是讲解原理的,对于不关心原理的小伙伴,可以直接使用现成的代码段就好。

        使用CRC算法时,主要关心CRC的多项式,CRC的初始值,CRC的异或值,还有需要校验的数据,CRC的数据位宽。

        下面以多项式0x1D, 初始值和异或值都是0x00为例,具体代码段如下。

#include "App_CRC_J1850.h"


#define CRC_USE_TABLE 1

#if CRC_USE_TABLE
#define BZIP2_TABLE_SIZE            (256u)

static const uint8_t crc_table[BZIP2_TABLE_SIZE] = {
  0x00,0x1D,0x3A,0x27,0x74,0x69,0x4E,0x53,0xE8,0xF5,0xD2,0xCF,0x9C,0x81,0xA6,0xBB
  ,0xCD,0xD0,0xF7,0xEA,0xB9,0xA4,0x83,0x9E,0x25,0x38,0x1F,0x02,0x51,0x4C,0x6B,0x76
  ,0x87,0x9A,0xBD,0xA0,0xF3,0xEE,0xC9,0xD4,0x6F,0x72,0x55,0x48,0x1B,0x06,0x21,0x3C
  ,0x4A,0x57,0x70,0x6D,0x3E,0x23,0x04,0x19,0xA2,0xBF,0x98,0x85,0xD6,0xCB,0xEC,0xF1
  ,0x13,0x0E,0x29,0x34,0x67,0x7A,0x5D,0x40,0xFB,0xE6,0xC1,0xDC,0x8F,0x92,0xB5,0xA8
  ,0xDE,0xC3,0xE4,0xF9,0xAA,0xB7,0x90,0x8D,0x36,0x2B,0x0C,0x11,0x42,0x5F,0x78,0x65
  ,0x94,0x89,0xAE,0xB3,0xE0,0xFD,0xDA,0xC7,0x7C,0x61,0x46,0x5B,0x08,0x15,0x32,0x2F
  ,0x59,0x44,0x63,0x7E,0x2D,0x30,0x17,0x0A,0xB1,0xAC,0x8B,0x96,0xC5,0xD8,0xFF,0xE2
  ,0x26,0x3B,0x1C,0x01,0x52,0x4F,0x68,0x75,0xCE,0xD3,0xF4,0xE9,0xBA,0xA7,0x80,0x9D
  ,0xEB,0xF6,0xD1,0xCC,0x9F,0x82,0xA5,0xB8,0x03,0x1E,0x39,0x24,0x77,0x6A,0x4D,0x50
  ,0xA1,0xBC,0x9B,0x86,0xD5,0xC8,0xEF,0xF2,0x49,0x54,0x73,0x6E,0x3D,0x20,0x07,0x1A
  ,0x6C,0x71,0x56,0x4B,0x18,0x05,0x22,0x3F,0x84,0x99,0xBE,0xA3,0xF0,0xED,0xCA,0xD7
  ,0x35,0x28,0x0F,0x12,0x41,0x5C,0x7B,0x66,0xDD,0xC0,0xE7,0xFA,0xA9,0xB4,0x93,0x8E
  ,0xF8,0xE5,0xC2,0xDF,0x8C,0x91,0xB6,0xAB,0x10,0x0D,0x2A,0x37,0x64,0x79,0x5E,0x43
  ,0xB2,0xAF,0x88,0x95,0xC6,0xDB,0xFC,0xE1,0x5A,0x47,0x60,0x7D,0x2E,0x33,0x14,0x09
  ,0x7F,0x62,0x45,0x58,0x0B,0x16,0x31,0x2C,0x97,0x8A,0xAD,0xB0,0xE3,0xFE,0xD9,0xC4
};


#endif
/**
 * @brief CRC8 SAE J1850 Function with initial value 0x00
 * 
 * @param data byte pointer of data for CRC calculation
 * @param len length of data
 * @return uint8_t result of CRC8 SAE J1850
 */
#if CRC_USE_TABLE

uint8_t u8fs_crc8_sae_j1850(uint8_t *data, uint8_t len)
{
  volatile uint16_t i;
  volatile uint8_t crc;
  volatile uint8_t tmp;

  crc = 0x00;
  for(i = 0; i < len; i ++)
  {
    tmp = crc ^ data[i];
    crc = crc_table[tmp];
  }
  return crc;
}
#else
uint8_t u8fs_crc8_sae_j1850(uint8_t *data, uint8_t len)
{
    uint8_t crc = 0x00;
    uint8_t i;
    while (len--)
    {
        crc ^= *data++;
        for (i = 0; i < 8; i++)
        {
            if (crc & 0x80)
            {
                crc = (crc << 1) ^ 0x1D;
            }
            else
            {
                crc <<= 1;
            }
        }
    }
    return crc;
}
#endif

uint8_t checksum_crc_j1850(uint8_t data1, uint8_t data2)
{
    uint8_t u8databeforecrc[2];
    
    u8databeforecrc[0] = data1;
    u8databeforecrc[1] = data2;
    
    return u8fs_crc8_sae_j1850(u8databeforecrc,2);
}

void app_crc_j1850_task(void)
{
    uint8_t checksum_crc = 0;
    
    checksum_crc = checksum_crc_j1850(TxIpduSWS_40A._c[0], TxIpduSWS_40A._c[1]);
    Com_SendSignal(COM_TXSIGSWS_CS,&checksum_crc);
}

        验证方法,网上有很多CRC计算器,这里推荐一个比较好用的在线CRC计算器CRC在线计算

        如下图所示:需要CRC校验的数据时0xA0,代码段运算后的CRC数据是0xA1。

        使用CRC计算器算出来的数据如下所示:

        CRC多字节校验数据举例,带校验的数据是0x10和0xA0,代码段校验后的数据是0x15。

        CRC计算器验证如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值