一、CRC16校验码的使用

现选择最常用的CRC-16校验,说明它的使用方法。

  根据Modbus协议,常规485通讯的信息发送形式如下:

  地址 功能码 数据信息 校验码

  1byte 1byte nbyte 2byte

  CRC校验是前面几段数据内容的校验值,为一个16位数据,发送时,低8位在前,高8为最后。

  例如:信息字段代码为: 1011001,校验字段为:1010。

  发送方:发出的传输字段为: 1 0 1 1 0 0 1 1 0 10

  信息字段 校验字段

  接收方:使用相同的计算方法计算出信息字段的校验码,对比接收到的实际校验码,如果相等及信息正确,不相等则信息错误;或者将接受到的所有信息除多项式,如果能够除尽,则信息正确。

二、CRC16校验码计算方法

 常用查表法和计算法。计算方法一般都是:

  (1)、预置1个16位的寄存器值0xFFFF,称此寄存器为CRC寄存器;

  (2)、把第一个8位二进制数据(既通讯信息帧的第一个字节)与16位的CRC寄存器的低

  8位相异或,把结果放于CRC寄存器,高八位数据不变;

  (3)、把CRC寄存器的内容右移一位(朝高位)用0填补最高位,并检查右移后的移出位;

  (4)、如果移出位为0:重复第3步(再次右移一位);如果移出位为1,CRC寄存器与一多

  项式(A001)进行异或;

  (5)、重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理;

  (6)、重复步骤2到步骤5,进行通讯信息帧下一个字节的处理;

  (7)、将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低

  字节进行交换;

  (8)、最后得到的CRC寄存器内容即为:CRC码。

  以上计算步骤中的多项式A001是8005按位颠倒后的结果。

  查表法是将移位异或的计算结果做成了一个表,就是将0~256放入一个长度为16位的寄存器中的低八位,高八位填充0,然后将该寄存器与多项式0XA001按照上述3、4步骤,直到八位全部移出,最后寄存器中的值就是表格中的数据,高八位、低八位分别单独一个表。

三、CRC16常见几个标准的算法

 CRC16常见的标准有以下几种,被用在各个规范中,其算法原理基本一致,就是在数据的输入和输出有所差异,下边把这些标准的差异列出,并给出C语言的算法实现。

  CRC16_CCITT:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结果与0x0000异或

  CRC16_CCITT_FALSE:多项式x16+x12+x5+1(0x1021),初始值0xFFFF,低位在后,高位在前,结果与0x0000异或

  CRC16_XMODEM:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在后,高位在前,结果与0x0000异或

  CRC16_X25:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或

  CRC16_MODBUS:多项式x16+x15+x5+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0x0000异或

  CRC16_IBM:多项式x16+x15+x5+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0x0000异或

  CRC16_MAXIM:多项式x16+x15+x5+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或

  CRC16_USB:多项式x16+x15+x5+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0xFFFF异或

四、CRC16的算法原理及程序

1.根据CRC16的标准选择初值CRCIn的值。

  2.将数据的第一个字节与CRCIn高8位异或。

  3.判断最高位,若该位为 0 左移一位,若为 1 左移一位再与多项式Hex码异或。

  4.重复3直至8位全部移位计算结束。

  5.重复将所有输入数据操作完成以上步骤,所得16位数即16位CRC校验码。

  根据算法原理与标准要求就能简单的写出具

/**
**************************************************************************************************
* @Brief    Single byte data inversion
* @Param
*            @DesBuf: destination buffer
*            @SrcBuf: source buffer
* @RetVal    None
* @Note      (MSB)0101_0101 ---> 1010_1010(LSB)
**************************************************************************************************
*/
void InvertUint8(unsigned char *DesBuf, unsigned char *SrcBuf)
{int i;unsigned char temp = 0;for(i = 0; i < 8; i++){if(SrcBuf[0] & (1 << i)){temp |= 1<<(7-i);}}DesBuf[0] = temp;
}/**
**************************************************************************************************
* @Brief    double byte data inversion
* @Param
*            @DesBuf: destination buffer
*            @SrcBuf: source buffer
* @RetVal    None
* @Note      (MSB)0101_0101_1010_1010 ---> 0101_0101_1010_1010(LSB)
**************************************************************************************************
*/
void InvertUint16(unsigned short *DesBuf, unsigned short *SrcBuf)
{int i;unsigned short temp = 0;for(i = 0; i < 16; i++){if(SrcBuf[0] & (1 << i)){temp |= 1<<(15 - i);}}DesBuf[0] = temp;
}unsigned short CRC16_CCITT(unsigned char *puchMsg, unsigned int usDataLen)
{unsigned short wCRCin = 0x0000;unsigned short wCPoly = 0x1021;unsigned char wChar = 0;while (usDataLen--){wChar = *(puchMsg++);InvertUint8(&wChar, &wChar);wCRCin ^= (wChar << 8);for(int i = 0; i < 8; i++){if(wCRCin & 0x8000){wCRCin = (wCRCin << 1) ^ wCPoly;}else{wCRCin = wCRCin << 1;}}}InvertUint16(&wCRCin, &wCRCin);return (wCRCin) ;
}unsigned short CRC16_CCITT_FALSE(unsigned char *puchMsg, unsigned int usDataLen)
{unsigned short wCRCin = 0xFFFF;unsigned short wCPoly = 0x1021;unsigned char wChar = 0;while (usDataLen--){wChar = *(puchMsg++);wCRCin ^= (wChar << 8);for(int i = 0; i < 8; i++){if(wCRCin & 0x8000){wCRCin = (wCRCin << 1) ^ wCPoly;}else{wCRCin = wCRCin << 1;}}}return (wCRCin) ;
}unsigned short CRC16_XMODEM(unsigned char *puchMsg, unsigned int usDataLen)
{unsigned short wCRCin = 0x0000;unsigned short wCPoly = 0x1021;unsigned char wChar = 0;while (usDataLen--){wChar = *(puchMsg++);wCRCin ^= (wChar << 8);for(int i = 0; i < 8; i++){if(wCRCin & 0x8000){wCRCin = (wCRCin << 1) ^ wCPoly;}else{wCRCin = wCRCin << 1;}}}return (wCRCin) ;
}unsigned short CRC16_X25(unsigned char *puchMsg, unsigned int usDataLen)
{unsigned short wCRCin = 0xFFFF;unsigned short wCPoly = 0x1021;unsigned char wChar = 0;while (usDataLen--){wChar = *(puchMsg++);InvertUint8(&wChar, &wChar);wCRCin ^= (wChar << 8);for(int i = 0;i < 8;i++){if(wCRCin & 0x8000){wCRCin = (wCRCin << 1) ^ wCPoly;}else{wCRCin = wCRCin << 1;}}}InvertUint16(&wCRCin, &wCRCin);return (wCRCin^0xFFFF) ;
}unsigned short CRC16_MODBUS(unsigned char *puchMsg, unsigned int usDataLen)
{unsigned short wCRCin = 0xFFFF;unsigned short wCPoly = 0x8005;unsigned char wChar = 0;while (usDataLen--){wChar = *(puchMsg++);InvertUint8(&wChar, &wChar);wCRCin ^= (wChar << 8);for(int i = 0; i < 8; i++){if(wCRCin & 0x8000){wCRCin = (wCRCin << 1) ^ wCPoly;}else{wCRCin = wCRCin << 1;}}}InvertUint16(&wCRCin, &wCRCin);return (wCRCin) ;
}unsigned short CRC16_IBM(unsigned char *puchMsg, unsigned int usDataLen)
{unsigned short wCRCin = 0x0000;unsigned short wCPoly = 0x8005;unsigned char wChar = 0;while (usDataLen--){wChar = *(puchMsg++);InvertUint8(&wChar, &wChar);wCRCin ^= (wChar << 8);for(int i = 0; i < 8; i++){if(wCRCin & 0x8000){wCRCin = (wCRCin << 1) ^ wCPoly;}else{wCRCin = wCRCin << 1;}}}InvertUint16(&wCRCin,&wCRCin);return (wCRCin) ;
}unsigned short CRC16_MAXIM(unsigned char *puchMsg, unsigned int usDataLen)
{unsigned short wCRCin = 0x0000;unsigned short wCPoly = 0x8005;unsigned char wChar = 0;while (usDataLen--){wChar = *(puchMsg++);InvertUint8(&wChar, &wChar);wCRCin ^= (wChar << 8);for(int i = 0; i < 8; i++){if(wCRCin & 0x8000){wCRCin = (wCRCin << 1) ^ wCPoly;}else{wCRCin = wCRCin << 1;}}}InvertUint16(&wCRCin, &wCRCin);return (wCRCin^0xFFFF) ;
}unsigned short CRC16_USB(unsigned char *puchMsg, unsigned int usDataLen)
{unsigned short wCRCin = 0xFFFF;unsigned short wCPoly = 0x8005;unsigned char wChar = 0;while (usDataLen--){wChar = *(puchMsg++);InvertUint8(&wChar, &wChar);wCRCin ^= (wChar << 8);for(int i = 0; i < 8; i++){if(wCRCin & 0x8000){wCRCin = (wCRCin << 1) ^ wCPoly;}else{wCRCin = wCRCin << 1;}}}InvertUint16(&wCRCin, &wCRCin);return (wCRCin^0xFFFF) ;
}

体程序:

C语言版CRC-16系列校验算法相关推荐

  1. 异或校验算法 c语言程序,C# 异或校验算法

    C# 的异或校验算法 直接上代码 public partial class FormCRC : Form { public FormCRC() { InitializeComponent(); } p ...

  2. bcc校验位怎么算的_BCC(异或校验)、CRC、LRC校验算法

    一.校验算法 BCC(Block Check Character/信息组校验码),好像也是常说的异或校验方法 CRC(Cyclic Redundancy Check/循环冗余校验) LRC(Longi ...

  3. 数据结构c语言版第16页,数据结构c语言版

    数据结构c语言版[编辑] 概述 <数据结构C语言版>本书的前半部分从抽象数据类型的角度讨论各种基本类型的数据结构及其应用;后半部分主要讨论查找和排序的各种实现方法及综合分析比较 出版信息 ...

  4. 【数据结构与算法——C语言版】1. 数据结构与算法简介

    概念 数据结构:"一组数据的存储结构" 算法:"操作数据的一组方法" 数据结构是为算法服务的,算法是要作用再特定的数据结构上的. 简言之,在编程实践中,我们可能 ...

  5. c语言 乱码转化为16进制_C语言版的16进制与字符串互转函数

    http://www.cnblogs.com/nio-nio/p/3309367.html /* // C prototype : void StrToHex(BYTE *pbDest, BYTE * ...

  6. 丁向荣单片机pdf_单片机原理与应用(C语言版)——基于STC15W201S系列单片机 丁向荣 纺著 9787121246357...

    第1章 STC15W201S单片机结构与工作原理 1.1 微型计算机结构与单片机 1.1.1 微型计算机的基本结构与工作原理 1.1.2 单片机概述 1.2 STC15W201S单片机结构与工作原理 ...

  7. 【转载】CRC32校验算法C语言版(查表法)

    先放原文链接:CRC32校验算法C语言版(查表法) 这几天搞串口通信,用到CRC32,把以前用到的东西整理一下,方便以后使用. STM32F103 芯片自带的CRC32硬件算法,匹配上位机CRC32算 ...

  8. crc校验算法程序c语言实现,CRC校验的快速算法的C语言实现

    CRC校验的快速算法的C语言实现 CC R校验的快速算法的C语言实现 颜国谷 (中原油田信息中心 4 70 ) 5 0 1 摘要:c c R循环冗余校验算法,是一种在数据存储和数据通讯领域中使用十分广 ...

  9. CRC-16原理及通用的16位CRC校验算法代码

    CRC-16原理及通用的16位CRC校验算法代码 循环冗余码校验英文名称为Cyclical Redundancy Check,简称CRC.它是利用除法及余数的原理来作错误侦测(Error Detect ...

最新文章

  1. java 匿名list,java创造匿名对象的两种方法
  2. C语言用户标准是什么,C语言系统用户标准管理系统.doc
  3. python工程师-史上最全Python工程师常见面试题集锦,有这一份就够了
  4. 从神经元到CNN、RNN、GAN…神经网络看本文绝对够了
  5. 转: Fedora 17 安装flash插件
  6. 如何正确清理C盘中DriverStore文件夹中文件?
  7. 更新json文件_忽略packagelock.json?
  8. 2017.9.7 JC loves Mkk 失败总结
  9. (转)分布式文件存储FastDFS(三)FastDFS配置
  10. 去年买彩票中了400多万
  11. Android窗口管理(2)——消息传递
  12. P2420 让我们异或吧 (树链剖分,异或前缀和)
  13. java 正则表达式 compile_JAVA 正则表达式
  14. UDS(ISO14229)诊断服务功能及描述完结篇
  15. win10服务器账号和密码,WIN10提示输入管理员用户和密码
  16. 2018_7_5 自撰imrotate和bwlabel的matlab代码实现
  17. 最新码支付源码+全套的程序+三网监控+易支付H5接口 2022年6月22号
  18. Mindjet MindManager 2019安装包
  19. macbook pro下载速度慢的解决方法
  20. 015-包、crate、模块

热门文章

  1. 计算机网络——VRRP(第一条冗余协议)
  2. H264学习(二)编码方法和编码工具简介
  3. 恋爱百分百-五十条经典的爱情观
  4. bom翻译中文_电器BOM表中英文对照
  5. kylin的cube的原理
  6. 怎么锻炼出顶尖程序员的编码套路(转)
  7. 008.西门子M440变频器USS通信
  8. Android GPS应用:动态获取位置信息
  9. ZZULIOJ-1107: 回文数猜想(函数专题)(Java)
  10. 5.19 英语单词小计