CRC校验:CRC校验是一种数据算法,是用来校验数据对错的。CRC校验函数把一帧数据除最后两个字节外,前边所有的字节进行特定的算法计算,计算完后生成了一个16bit的数据,作为CRC校验码,添加在一帧数据的最后。接收方接收到数据后,同样会把前边的字节进行CRC计算,计算完了再和发过来的16bit的CRC数据进行比较,如果相同则认为数据正常,没有出错,如果比较不相同,则说明数据在传输中发生了错误,这帧数据将被丢弃,就像没收到一样,而发送方会在得不到回应后做相应的处理错误处理。

CRC校验数据处理思路:将整个RTU帧看作是一个连续的二进制数据串,校验时只涉及数据位,舍去起始位,停止位和任选的奇偶校验位。

RTU模式的每个字节的位是这样分布的:1个起始位、8个数据位,最小有效位先发送、1个奇偶校验位(如果无校验则没有这一位)、1位停止位(有校验位时)或者2个停止位(无校验位时)。

产生CRC码的步骤如下:

  1. 预置一个16位的寄存器为全1(即十六进制FFFFH),称此寄存器为CRC寄存器;
  2. 把第一个8位数据与CRC寄存器的低8位相异或,结果放回CRC寄存器;
  3. 把16位CRC寄存器右移一位,用0添补最高位,检测移出位:
  4. 如果移出位为0,则重复第3步骤(再次移出);如果移出位为1,则CRC寄存器与多项式A001H相异或,结果放回CRC寄存器;
  5. 重复第3、4步骤,直至移出8位;
  6. 将下一个8位数据与CRC寄存器低8位相异或,结果放回CRC寄存器,重复第2、3、4、5步骤;
  7. 最后得到的CRC寄存器内容即为产生的CRC校验码。

封装后的CRC校验函数源码如下:

/****************************CRC16校验函数源码****************************/

/* CRC16计算函数,ptr-数据指针,len-数据长度,函数返回-计算出的CRC16数值*/

unsigned int GetCRC16(unsigned char *ptr,  unsigned char len)

{

unsigned int index;

unsigned char crch = 0xFF;  //高CRC字节

unsigned char crcl = 0xFF;  //低CRC字节

unsigned char code TabH[] = {  //CRC高位字节值表

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,

0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,

0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,

0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,

0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,

0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,

0x80, 0x41, 0x00, 0xC1, 0x81, 0x40

} ;

unsigned char code TabL[] = {  //CRC低位字节值表

0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,

0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,

0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,

0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,

0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,

0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,

0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,

0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,

0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,

0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,

0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,

0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,

0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,

0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,

0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,

0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,

0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,

0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,

0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,

0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,

0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,

0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,

0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,

0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,

0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,

0x43, 0x83, 0x41, 0x81, 0x80, 0x40

} ;

while (len–)  //计算指定长度的CRC

{

index = crch ^ *ptr++;

crch = crcl ^ TabH[index];

crcl = TabL[index];

}
        
    return ((crch<<8) | crcl);

}

//说明,一般情况下关于CRC校验的算法,会用即可,无需花大精力研究。

            </div>

MODBUS-RTU CRC校验算法及函数源码相关推荐

  1. OpenCV 源码中分水岭算法 watershed 函数源码注解

    为了研究分水岭算法,阅读了OpenCV 2.4.9 中watershed函数的源码实现部分,代码位于 opencv\sources\modules\imgproc\src\segmentation.c ...

  2. modbus c语言校验算法,Modbus CRC校验算法

    终于找到了 Modbus CRC 校验算法 算法一: unsigned int calccrc(uchar crcbuf,uint crc) { uchar i; crc=crc ^ crcbuf; ...

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

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

  4. 【FPGA】CRC校验算法从数学原理到代码实现

    老规矩,转b站 [[FPGA]CRC校验算法从数学原理到代码实现-哔哩哔哩]

  5. CRC校验算法的数学原理(上)

    介绍   CRC是Cyclic Redundancy Check的缩写,用中文来讲,就是 循环冗余校验.是一种通过对数据产生固定位数校验码以备侦测数据错误的数据校验技术,主要用来侦测数据传输错误,也可 ...

  6. c# 如何编写CRC校验算法

    在C#中编写CRC校验算法,可以使用以下步骤: 首先需要确定CRC校验的多项式和初始值.根据具体的需求和应用场景,选择合适的CRC多项式和初始值. 定义一个计算CRC校验值的函数,函数的输入参数为待校 ...

  7. 16进制(CRC16)(MODBUS RTU通讯)校验码在线计算器

    最近在项目上遇到,用485协议命令控制灯光继电器的开关需要计算16进制(CRC16)(MODBUS RTU通讯)校验码来写控制命令,这种在网上有现成的计算器,我们直接使用即可,以下为我用的一个计算器的 ...

  8. vxworks环形缓冲区函数源码分析

    VxWorks环形缓冲区函数源码分析 ​ by zn 文章目录 VxWorks环形缓冲区函数源码分析 0.使用环形缓冲区的注意事项 1.环形缓冲区结构体定义 2.rngCreate--创建环形缓冲区 ...

  9. OpenCV resize函数源码解析——加速方法

    相信大家应该经常会用到OpenCV中的函数resize(),当我们想放大或者缩小图像的时候,会用到这个函数进行图像缩放,其中最核心的便是对图像的像素进行插值处理. 这里的插值interpolation ...

  10. LMDIF_函数源码

    函数源码: /* lmdif.f -- translated by f2c (version 20020621).You must link the resulting object file wit ...

最新文章

  1. 一盘红烧肉告诉你,本科、硕士和博士区别太大了!
  2. linux c++ 函数 查看,在C++ man pages中查询C++的函数
  3. POE交换机应用技术知识大全
  4. javascript实现jsonp跨域问题+原理
  5. Spring中yml多环境配置
  6. 【Python3网络爬虫开发实战】 1.7-App爬取相关库的安装
  7. 解决HuggingFace加载预训练模型时报错TypeError: expected str, bytes or os.PathLike object, not NoneType
  8. 数据结构关键路径_2021年厦门大学考研丨能源学院845数据结构参考书目推荐
  9. Jade平台的下载与原装
  10. 如何保证MQ消息队列的高可用
  11. unit英语读音_unit是什么意思_unit翻译_读音_用法_翻译
  12. 计算机主板复位电路的组成,电脑主板复位电路工作原理
  13. 如何综合掌握 DB2 和 Informix
  14. 数据库的故障及其恢复策略
  15. openCV ROI
  16. IDS反病毒与APT的具体介绍
  17. 01-学习笔记(webstorm自定义模板代码)【新手上路,多多关照】
  18. 初学(一):不积跬步,无以成千里 【基础知识必备】
  19. vue 导入第三方js实例对象
  20. 学习前端需要知道的知识

热门文章

  1. html修改每页显示数量,JS实现动态设置每页显示固定行数
  2. ArcGIS图解建模工具与DEM提取山脊、山谷线(水文分析、表面分析)
  3. 学算法先学数据结构?是否是无稽之谈?
  4. 【python】10行代码下载B站弹幕
  5. linux源码(含有kfifo)下载
  6. 【小白视角】大数据基础实践(二)Hadoop环境搭建与测试
  7. 阵列信号处理 窄带信号与包络
  8. java voip 的sip服务器搭建_SIP协议开源SIP服务器搭建和客户端安装
  9. UnixVi命令详解
  10. 服务零售全场景,苏宁机器人“分身有术”