// 生成modbus CRC16数据

     CRC-16 / MODBUS :

1)CRC寄存器初始值为 FFFF;即16个字节全为1;

2)CRC-16 / MODBUS的多项式A001H (1010 0000 0000 0001B) ‘H’表示16进制数,‘B’表示二进制数

计算步骤为: 
(1).预置 16 位寄存器为十六进制 FFFF(即全为 1) ,称此寄存器为 CRC  寄存器;  
(2).把第一个 8  位数据与 16  位 CRC  寄存器的低位相异或,把结果放于 CRC  寄
存器; 

(3).检测相异或后的CRC寄存器的最低位,若最低位为1:CRC寄存器先右移1位,再与多项式A001H进行异或;若为0,则CRC寄存器右移1位,无需与多项式进行异或。

(4).重复步骤 3  ,直到右移 8  次,这样整个 8 位数据全部进行了处理; 
(5).重复步骤 2  到步骤4,进行下一个 8  位数据的处理; 
(6).最后得到的 CRC  寄存器即为 CRC 码。 

附参考:

数据(16进制):01 03 61 00 00 02 CRC校验:F7 DB

附C语言实现代码:

#include <stdio.h>

int main(void)
{
    unsigned short tmp = 0xffff;
    unsigned short ret1 = 0;
    unsigned char buff[6] = {0};
    buff[0] = 0x01;
    buff[1] = 0x03;
    buff[2] = 0x61;
    buff[3] = 0x00;
    buff[4] = 0x00;
    buff[5] = 0x02;

    for(int n = 0; n < 6; n++){/*此处的6 -- 要校验的位数为6个*/
        tmp = buff[n] ^ tmp;
        for(int i = 0;i < 8;i++){  /*此处的8 -- 指每一个char类型又8bit,每bit都要处理*/
            if(tmp & 0x01){
                tmp = tmp >> 1;
                tmp = tmp ^ 0xa001;
            }
            else{
                tmp = tmp >> 1;
            }
        }
    }
    /*CRC校验后的值*/
    printf("%X\n",tmp);
    /*将CRC校验的高低位对换位置*/
    ret1 = tmp >> 8;
    ret1 = ret1 | (tmp << 8);
    printf("ret: %X\n",ret1);
    return 0;
}
输出结果:

F7DB
ret: DBF7

// 生成modbus CRC16数据
function CRC16(sSrc:shortstring):shortstring;
var
  tmp: word;
  ret1: word;
  buff: array of byte;
  n:integer;
  i:integer;

  ilen:Integer; //ssrc length
begin
  if trim(ssrc)=‘‘ then exit;

  tmp:= $FFFF;
  ret1:= 0;

  ssrc:= Trim(ssrc);
  ssrc:= StringReplace(sSrc,‘ ‘,‘‘,[rfReplaceAll]);
  ilen:= length(ssrc);

  SetLength(buff,ilen div 2);
  i:=1;
  while i<ilen do
  begin
    buff[(i-1)div 2]:= StrToInt(‘$‘+sSrc[i]+sSrc[i+1]);
    i:=i+2;
  end;

  for n := 0 to Length(buff)-1 do  //*此处的6 -- 要校验的位数为6个*/
  begin
    tmp:= buff[n] xor tmp;
    for I := 0 to 7 do  //*此处的8 -- 指每一个char类型又8bit,每bit都要处理*/
    begin
      if(tmp and $01)<>0 then
      begin
        tmp:= tmp shr 1;
        tmp:= tmp xor $A001;
      end
      else
      begin
        tmp:= tmp shr 1;
      end;
    end;
  end;

  ret1 := tmp shr 8;        //*将CRC校验的高低位对换位置*/
  ret1 := ret1 or (tmp shl 8);
  Result:= IntToHex(ret1,4);

  //返回16进制串 用 空格 分开  crc 暂定 2字节
  result:= Result[1]+Result[2]+‘ ‘+Result[3]+Result[4];
end;

原文地址:https://www.cnblogs.com/tobetterlife/p/12161832.html

时间: 2024-10-18 10:10:48

// 生成modbus CRC16数据的相关文章

Modbus CRC16 校验计算函数

// CRC 高位字节值表 static const uint8_t auchCRCHi[] = { 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, 0

开源 免费 java CMS - FreeCMS1.9 移动APP生成栏目列表数据

项目地址:http://www.freeteam.cn/ 生成栏目列表数据 提取当前管理站点下允许移动APP访问的栏目列表,生成json数据到/site/站点目录/mobile/channels.html页面. 从左侧管理菜单点击生成栏目列表数据进入. 点击确定即可. 开源 免费 java CMS - FreeCMS1.9 移动APP生成栏目列表数据,布布扣,bubuko.com

开源 免费 java CMS - FreeCMS1.9 移动APP生成站点列表数据

项目地址:http://www.freeteam.cn/ 生成站点列表数据 提取允许移动APP访问的站点列表,生成json数据到/mobile/index.html页面. 从左侧管理菜单点击生成站点列表数据进入. 点击确定即可. 开源 免费 java CMS - FreeCMS1.9 移动APP生成站点列表数据,布布扣,bubuko.com

pu0quqbcSerlet生成jS0N格式数据并用

榆已 pu0quqbcSerlet生成jS0N格式数据并用

利用存储过程生成大量的数据(oracle,mysql)

在进行查询操作的性能测试时,往往需要测试大数据量模式下的查询功能的性能,这是就需要我们去创造一些测试数据来填充数据库,来模拟真是环境,造数据的方式有很多种,可以使用loadrunner,jmeter等压测工具压一些数据进去,但是这样做的效率不高,下面记录一个快速生成大量有规则数据的方法,那就是数据库的存储过程函数,通过运行函数快速的生成大量的数据.(使用这个方法的前提是你需要足够了解你要操作的数据库表的结构) 1.oracle数据库 DECLARE --声明函数 i INT; BEGIN i:=

Python+Mysql生成zabbix统计数据

先大概了解一下zabbix数据库结构: 1.groups表 可以根据组名查到组ID 2.找到组ID就可以根据组ID找出这个组下面的所有服务器的ID,这个关系在hosts_groups表里面: 3.有了hostid就可以在hosts表里查看这台机器的基本信息了: items表则可以根据hostid查出这台服务器的所有监控项: 4.终于在items表查到itemid,利用这个itemid在trends和trends_uint这两个表中统计出我们需要的数据 我python水平挺菜的,很多面向对象的功能

开源 免费 java CMS - FreeCMS1.9 移动APP生成网站列表数据

项目地址:http://www.freeteam.cn/ 生成网站列表数据 提取同意移动APP訪问的网站列表,生成json数据到/mobile/index.html页面. 从左側管理菜单点击生成网站列表数据进入. 点击确定就可以.

CRC16数据检验-用于AISG协议通讯数据检验

CRC16数据检验,欧洲标准 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WorkTool_AISG { public class CRC { private static ushort[] crc16table =new ushort[] { 0x0000, 0x1189, 0x2312,

ARToolKit从图片生成特征点数据

文档原文 工具下载 步骤 1 决定分辨率 首先根据你最后marker的大小,决定图片的分辨率 分辨率不要太大,太大的话在跟踪时会占用很多内存和CPU 分辨率也不要太小,太小的话摄像机距离近时会没有足够的特征点来跟踪 你的marker的物理尺寸是多少?如A4是210mm*297mm 跟踪时你的摄像机距离最近会有多近?这一般和图片分辨率也有关系,一般情况下黑白激光打印机是300dpi,彩色打印机一般是150dpi 现在你可以使用ARUnity5-5.3.1-tools-win\bin下的工具chec