102 lines
2.4 KiB
C
102 lines
2.4 KiB
C
|
#include "crc16.h"
|
|||
|
|
|||
|
static uint8_t crc_tab16_init = 0;
|
|||
|
static uint16_t crc_tab16[256];
|
|||
|
|
|||
|
/*
|
|||
|
* uint16_t crc_16( const unsigned char *input_str, size_t num_bytes );
|
|||
|
*
|
|||
|
*函数crc_16()一次计算一个字节的16位CRC16
|
|||
|
*其开头已传递给函数的字符串。的数量
|
|||
|
*要检查的字节也是一个参数。字符串中的字节数为
|
|||
|
*受恒定大小最大值的限制。
|
|||
|
*/
|
|||
|
uint16_t crc_16(const uint8_t *input_str, uint16_t num_bytes)
|
|||
|
{
|
|||
|
uint16_t crc;
|
|||
|
const uint8_t *ptr;
|
|||
|
uint16_t a;
|
|||
|
if (!crc_tab16_init)
|
|||
|
init_crc16_tab();
|
|||
|
crc = CRC_START_16;
|
|||
|
ptr = input_str;
|
|||
|
if (ptr != NULL)
|
|||
|
for (a = 0; a < num_bytes; a++)
|
|||
|
{
|
|||
|
crc = (crc >> 8) ^ crc_tab16[(crc ^ (uint16_t)*ptr++) & 0x00FF];
|
|||
|
}
|
|||
|
return crc;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* uint16_t crc_modbus( const unsigned char *input_str, size_t num_bytes );
|
|||
|
*
|
|||
|
*函数crc_modbus()一次计算16位modbus循环冗余校验
|
|||
|
*一个字节字符串,其开头已被传递给函数。这
|
|||
|
*要检查的字节数也是一个参数。
|
|||
|
*/
|
|||
|
|
|||
|
uint16_t crc_modbus(const uint8_t *input_str, uint16_t num_bytes)
|
|||
|
{
|
|||
|
uint16_t crc;
|
|||
|
const uint8_t *ptr;
|
|||
|
uint16_t a;
|
|||
|
|
|||
|
if (!crc_tab16_init)
|
|||
|
init_crc16_tab();
|
|||
|
|
|||
|
crc = CRC_START_MODBUS;
|
|||
|
ptr = input_str;
|
|||
|
if (ptr != NULL)
|
|||
|
for (a = 0; a < num_bytes; a++)
|
|||
|
{
|
|||
|
|
|||
|
crc = (crc >> 8) ^ crc_tab16[(crc ^ (uint16_t)*ptr++) & 0x00FF];
|
|||
|
}
|
|||
|
return crc;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* uint16_t update_crc_16( uint16_t crc, unsigned char c );
|
|||
|
*
|
|||
|
*函数update_crc_16()根据
|
|||
|
*前一个循环冗余校验值和下一个要检查的数据字节。
|
|||
|
*/
|
|||
|
uint16_t update_crc_16(uint16_t crc, uint8_t c)
|
|||
|
{
|
|||
|
if (!crc_tab16_init)
|
|||
|
init_crc16_tab();
|
|||
|
return (crc >> 8) ^ crc_tab16[(crc ^ (uint16_t)c) & 0x00FF];
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* static void init_crc16_tab( void );
|
|||
|
*
|
|||
|
*为了获得最佳性能,使用CRC16例程查找带有值的表
|
|||
|
*可以直接在异或算法中使用的算法。
|
|||
|
*查找表首次由init_crc16_tab()例程计算
|
|||
|
*调用循环冗余校验函数。
|
|||
|
*/
|
|||
|
void init_crc16_tab(void)
|
|||
|
{
|
|||
|
uint16_t i;
|
|||
|
uint16_t j;
|
|||
|
uint16_t crc;
|
|||
|
uint16_t c;
|
|||
|
for (i = 0; i < 256; i++)
|
|||
|
{
|
|||
|
crc = 0;
|
|||
|
c = i;
|
|||
|
for (j = 0; j < 8; j++)
|
|||
|
{
|
|||
|
if ((crc ^ c) & 0x0001)
|
|||
|
crc = (crc >> 1) ^ CRC_POLY_16;
|
|||
|
else
|
|||
|
crc = crc >> 1;
|
|||
|
c = c >> 1;
|
|||
|
}
|
|||
|
crc_tab16[i] = crc;
|
|||
|
}
|
|||
|
crc_tab16_init = 1;
|
|||
|
}
|