📄 lib_crc.c
字号:
#include "lib_crc.h"
/*******************************************************************\
* *
* Library : lib_crc *
* File : lib_crc.c *
* Author : Lammert Bies 1999-2007 *
* E-mail : info@lammertbies.nl *
* Language : ANSI C *
* *
* *
* Description *
* =========== *
* *
* The file lib_crc.c contains the private and public func- *
* tions used for the calculation of CRC-16, CRC-CCITT and *
* CRC-32 cyclic redundancy values. *
* *
* *
* Dependencies *
* ============ *
* *
* lib_crc.h CRC definitions and prototypes *
* *
* *
* Modification history *
* ==================== *
* *
* Date Version Comment *
* *
* 2007-04-01 1.15 Added CRC16 calculation for Modbus *
* *
* 2007-03-28 1.14 Added CRC16 routine for Sick devices *
* *
* 2005-12-17 1.13 Added CRC-CCITT with initial 0x1D0F *
* *
* 2005-05-14 1.12 Added CRC-CCITT with start value 0 *
* *
* 2005-02-05 1.11 Fixed bug in CRC-DNP routine *
* *
* 2005-02-04 1.10 Added CRC-DNP routines *
* *
* 1999-02-21 1.01 Added FALSE and TRUE mnemonics *
* *
* 1999-01-22 1.00 Initial source *
* *
\*******************************************************************/
/*******************************************************************\
* *
* #define P_xxxx *
* *
* The CRC's are computed using polynomials. The coefficients *
* for the algorithms are defined by the following constants. *
* *
\*******************************************************************/
#define P_16 0xA001
#define P_32 0xEDB88320L
#define P_CCITT 0x1021
#define P_DNP 0xA6BC
#define P_SICK 0x8005
/*******************************************************************\
* *
* static int crc_tab...init *
* static unsigned ... crc_tab...[] *
* *
* The algorithms use tables with precalculated values. This *
* speeds up the calculation dramaticaly. The first time the *
* CRC function is called, the table for that specific calcu- *
* lation is set up. The ...init variables are used to deter- *
* mine if the initialization has taken place. The calculated *
* values are stored in the crc_tab... arrays. *
* *
* The variables are declared static. This makes them invisi- *
* ble for other modules of the program. *
* *
\*******************************************************************/
static int crc_tab16_init = FALSE;
static int crc_tab32_init = FALSE;
static int crc_tabccitt_init = FALSE;
static int crc_tabdnp_init = FALSE;
static unsigned short crc_tab16[256];
static unsigned long crc_tab32[256];
static unsigned short crc_tabccitt[256];
static unsigned short crc_tabdnp[256];
/*******************************************************************\
* *
* static void init_crc...tab(); *
* *
* Three local functions are used to initialize the tables *
* with values for the algorithm. *
* *
\*******************************************************************/
static void init_crc16_tab( void );
static void init_crc32_tab( void );
static void init_crcccitt_tab( void );
static void init_crcdnp_tab( void );
/*******************************************************************\
* *
* unsigned short update_crc_ccitt( unsigned long crc, char c ); *
* *
* The function update_crc_ccitt calculates a new CRC-CCITT *
* value based on the previous value of the CRC and the next *
* byte of the data to be checked. *
* *
\*******************************************************************/
unsigned short update_crc_ccitt( unsigned short crc, char c ) {
unsigned short tmp, short_c;
short_c = 0x00ff & (unsigned short) c;
if ( ! crc_tabccitt_init ) init_crcccitt_tab();
tmp = (crc >> 8) ^ short_c;
crc = (crc << 8) ^ crc_tabccitt[tmp];
return crc;
} /* update_crc_ccitt */
/*******************************************************************\
* *
* unsigned short update_crc_sick( *
* unsigned long crc, char c, char prev_byte ); *
* *
* The function update_crc_sick calculates a new CRC-SICK *
* value based on the previous value of the CRC and the next *
* byte of the data to be checked. *
* *
\*******************************************************************/
unsigned short update_crc_sick( unsigned short crc, char c, char prev_byte ) {
unsigned short short_c, short_p;
short_c = 0x00ff & (unsigned short) c;
short_p = ( 0x00ff & (unsigned short) prev_byte ) << 8;
if ( crc & 0x8000 ) crc = ( crc << 1 ) ^ P_SICK;
else crc = crc << 1;
crc &= 0xffff;
crc ^= ( short_c | short_p );
return crc;
} /* update_crc_sick */
/*******************************************************************\
* *
* unsigned short update_crc_16( unsigned long crc, char c ); *
* *
* The function update_crc_16 calculates a new CRC-16 value *
* based on the previous value of the CRC and the next byte *
* of the data to be checked. *
* *
\*******************************************************************/
unsigned short update_crc_16( unsigned short crc, char c ) {
unsigned short tmp, short_c;
short_c = 0x00ff & (unsigned short) c;
if ( ! crc_tab16_init ) init_crc16_tab();
tmp = crc ^ short_c;
crc = (crc >> 8) ^ crc_tab16[ tmp & 0xff ];
return crc;
} /* update_crc_16 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -