在工业控制中,Modbus RTU CRC16的校验码用的比较广泛,包括本人富士产品中,PC与伺服电机以及PC与VP系列的变频器的Modbus RTU通讯中都使用到了CRC16.

    而对CRC16的计算的方式基本上有2种:第一种,使用双循环依照CRC的计算方法进行计算,第二种,采用查表的方式。本人愚钝无比,从网络上搜来的查表法都与实际的正确CRC16的结果有所差异,因此编写了一个小程序供自己使用。
   软件的界面很简单,输入诸如“010303020014”的值,然后每2个字符作为一个字节,填入字节数,然后就可以计算出校验码,校验码的多项式为:X16+X15+X2+1.
 
 
实现的源代码如下:
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    Edit3: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Memo1: TMemo;
    Label4: TLabel;
  function CalCRC16(AData:array of Byte;AStart,AEnd:Integer):Word;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
//××××××××××××××××××××××××××
// CalCRC16用于计算Modbus RTU的CRC16
// 多项式公式为X16+X15+X2+1
//××××××××××××××××××××××××××
function TForm1.CalCRC16(AData:array of Byte;AStart,AEnd:Integer):Word;
const
  GENP=$A001;  //多项式公式X16+X15+X2+1(1100 0000 0000 0101)
var
  crc:Word;
  i:Integer;
  tmp:Byte;
procedure CalOneByte(AByte:Byte);  //计算1个字节的校验码
var
j:Integer;
begin
  crc:=crc xor AByte;   //将数据与CRC寄存器的低8位进行异或
  for j:=0 to 7 do      //对每一位进行校验
  begin
    tmp:=crc and 1;        //取出最低位
    crc:=crc shr 1;        //寄存器向右移一位
    crc:=crc and $7FFF;    //将最高位置0
    if tmp=1 then         //检测移出的位,如果为1,那么与多项式异或
      crc:=crc xor GENP;
      crc:=crc and $FFFF;
  end;
end;
begin
  crc:=$FFFF;             //将余数设定为FFFF
  for i:=AStart to AEnd do   //对每一个字节进行校验
    CalOneByte(AData[i]);
  Result:=crc;
end;
 
 
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Data:array[0..255] of Byte;
  i,j,Count:Integer;
  Res:Word;
  szData:string;
begin
  szData:=Form1.Edit2.Text;    //读入欲校验的字符串
  Count:=StrToInt(form1.Edit3.Text); //读入需要计算的字符串长度
  i:=1;
  j:=0;
  for j:=0 to Count-1 do
  begin
    if (i mod 2)=0 then    //每2个字符放入一个字节中
         i:=i+1;
    if i>=Length(szData) then
        exit;
    Data[j]:=StrToInt('$'+copy(szData,i,2)); //取出字符并转换为16进制数
    i:=i+1;
  end;
 
  Res:=CalCRC16(Data,Low(Data),Count-1);
  form1.Edit1.Text:=IntToHex(Res,4);
end;
 
end.
 
原贴:
http://blog.163.com/shcima@yeah/blog/static/107821988201062105441133/
 
 

你这个程序有问题,有空联系我,不对。我的QQ是992725706

2011-08-21 14:31

cvlsam 回复 dfdfdfdf
已经用于实际项目中了……
2015-05-07 11:09

15751010184 回复 dfdfdfdf
不要怀疑这个程序的正确性。。。。不过modbus上使用可能是需要把高低对调一下,别的我就不知道了!

  Res:=CalCRC16(Data,Low(Data),Count-1);
  crc:=IntToHex(Res,4);
  crcL:=crc[3]+crc[4] ;
  crcH:=crc[1]+crc[2] ;
  memo1.Text:=crcL+crcH;
2015-05-07 11:04

不过在modbus通讯字符串里,那个得到的校验码确实需要把高位和低位对调一下。。。但是任然万分感激楼主把我从一个星期的蛋疼中解救出来。。。。楼主我能加你qq么?以后多请教一下你。。。。
2015-05-07 11:00

真是感激啊。。。。。。位校验程序网上很多,关键就在需要校验的字符怎么处理再给予校验,各种坑啊。。。。楼主贴出了字符到校验的处理全过程。。。。。业界良心啊!!!!!!!!
2014-02-20 23:03

1
您太厉害了 好佩服
2013-07-21 17:41

patchhome

好像计算出来的高2位和低2位应该对调才和设备的对上。

2011-05-16 08:40

2010-09-19 10:50

恩,我也才刚冲学校走出来, 单位要求学习delphi,先在编城中有关通讯这块遇到问题,主要用modbus协议CRC的算法,有空向您多请教
 
 
 
 
 
 
 
 
 
 

如何使用Delphi编写Modbus RTU CRC16的校验码的更多相关文章

  1. C语言实现的CRC16/CCITT-FALSE校验码函数

    要求:输入字符串“00 AA FF CC AA 01 00” 得到校验码“79B1” 方法1: // ConsoleApplication1.cpp: 定义控制台应用程序的入口点. // #inclu ...

  2. Delphi Modbus RTU CRC16校验码

    function CheckCrc16(const ABuf; ALen: Integer): Boolean;var uwTemp: WORD; i, j: BYTE; P: PByte;begin ...

  3. Modbus RTU通信协议详解以及与Modbus TCP通信协议之间的区别和联系

    Modbus通信协议由Modicon公司(现已经为施耐德公司并购,成为其旗下的子品牌)于1979年发明的,是全球最早用于工业现场的总线规约.由于其免费公开发行,使用该协议的厂家无需缴纳任何费用,Mod ...

  4. PHP CRC16 校验码的算法怎么使用

    PHP CRC16 校验码的算法如何使用最近用到CRC16, 我现在就是要把 010301180001 算出CRC16的校验码,通过其他工具,可以得到 校验码是 05F1 最后完整的代码就是 0103 ...

  5. CRC16冗余循环检测计算器-好用。modbus RTU

    开始使用 http://cht.nahua.com.tw/index.php?url=http://cht.nahua.com.tw/software/crc16/&key=Modbus,%2 ...

  6. Modbus协议栈实现Modbus RTU多主站支持

    前面我们已经详细讲解过Modbus协议栈的开发过程,并且利用协议栈封装了Modbus RTU主站和从站,Modbus TCP服务器与客户端,Modbus ASCII主站与从站应用.但在使用过程中,我们 ...

  7. C# 开发Modbus Rtu客户端 modbus测试Demo,Modbus 串口通信 , 虚拟MODBUS-RTU测试

    前言 本文将使用一个NuGet公开的组件技术来实现一个ModBus RTU的客户端,方便的对Modbus rtu的服务器进行读写,这个服务器可以是电脑端C#设计的,也可以是PLC实现的,也可以是其他任 ...

  8. modbus ASCII和MODBUS RTU区别

    下表是MODBUS ASCII协议和RTU协议的比较: 协议 开始标记 结束标记 校验 传输效率 程序处理 ASCII :(冒号) CR,LF LRC 低 直观,简单,易调试 RTU 无 无 CRC ...

  9. Modbus RTU程序开发解读

    Modbus是很好的串口通信协议,其中RTU协议最为常用,通过Modbus RTU,我们可以轻松读写串口信息. 从官网下载libModbus,观察modbus.h可知关键的结构体为: typedef ...

随机推荐

  1. HTML5初识Canvas

    HTML5初识Canvas <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  2. Nginx 战斗准备 —— 优化指南

    大多数的Nginx安装指南告诉你如下基础知识——通过apt-get安装,修改这里或那里的几行配置,好了,你已经有了一个Web服务器了!而且,在大多数情况下,一个常规安装的nginx对你的网站来说已经能 ...

  3. tomcat调优(Mark)

    http://blog.csdn.net/jinwanmeng/article/details/7756591

  4. 【bzoj4994】[Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组

    题目描述 给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数 样例输入 4 3 2 4 4 1 3 2 1 样例输 ...

  5. [LOJ #2162]「POI2011」Garbage

    题目大意:给一张$n$个点$m$条边的无向图,每条边是黑色的或白色的,要求变成一个目标颜色.可以从任意一个点开始,走一个简单环,回到开始的点,所经过的边颜色翻转.可以走无数次.问是否有一个方案完成目标 ...

  6. [洛谷P4178]Tree

    题目大意:给一棵树,问有多少条路径长度小于等于$k$ 题解:点分治 卡点:无 C++ Code: #include <cstdio> #include <algorithm> ...

  7. ndk开发-ffmpeg编译

    进入模拟器shell: D:\Users\zhouhaitao\AppData\Local\Android\sdk\platform-tools\adb shell ndk编译链接静态库: LOCAL ...

  8. freemarker的简单入门程序

    本文主要介绍了freemarker的常用标签<#list>   <#import>  <#assign>  <#if> <#else> &l ...

  9. 服务器 阿里云服务器Ubuntu挂载数据盘

    服务器 阿里云服务器Ubuntu挂载数据盘  转自:http://www.codingyun.com/article/24.html coding云运行在阿里云的Ubuntu 12.04 64位操作系 ...

  10. POJ3668 Game of Lines

     Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6791   Accepted: 2523 Description Farm ...