• 16位CRC校验_Delphi


    unit Modbus_main;
    
    {$mode objfpc}{$H+}
    
    interface
    
    uses
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
    
    type
    
      { TForm1 }
    
      TForm1 = class(TForm)
        Button1: TButton;
        Edit1: TEdit;
        Edit2: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        Label5: 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 *.lfm}
    
    { TForm1 }
    
    function TForm1.CalCRC16(AData:array of Byte;AStart,AEnd:Integer):Word;  //16位CRC校验方法
    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,k,WordLength: integer;
       Edit1temp:string;
       Edit1Value:string;
       CRCtemp:string;
       Res :Word;
    begin
       Edit1temp := Edit1.Text;
       Edit1Value :=StringReplace(Edit1temp,' ','',[rfReplaceAll]); //取到待校验字符串并去掉字符串中间的所有空格
       k:=Length(Edit1Value);
       WordLength :=trunc(k/2);//trunc函数取整数部分的值
       begin
         i :=1;
         j :=0;
         for j:=0 to WordLength-1 do
         begin
          if (i mod 2)=0 then    //每2个字符放入一个字节中
             i:=i+1;
           if i>=Length(Edit1Value) then
            exit;
             Data[j]:=StrToInt('$'+copy(Edit1Value,i,2)); //取出字符并转换为16进制数
             i:=i+1;
         end;
         Res:=CalCRC16(Data,Low(Data),WordLength-1);
         CRCtemp:=IntToHex(Res,4);
         if(WordLength<7) then
         Edit2.Text:=RightStr(CRCtemp,2)+' '+LeftStr(CRCtemp,2) //小于6组数说明是上位机发送的数据,需要将得到的CRC校验结果的高低位交换,再显示
         else
         Edit2.Text:=LeftStr(CRCtemp,2)+' '+RightStr(CRCtemp,2);//大于6组数说明是上位机收到的数据,不需要将得到的CRC校验结果的高低位交换,直接显示
       end
    end;
    
    end.
    

     

  • 相关阅读:
    第三篇 从EXCEL电子表格到数据库
    第二篇 顾问实施ERP与医生看病过程类比
    第一篇 ERP是什么?-从道的层面浅谈我的理解
    Order to Cash Process
    Back to Back Order Process
    OracleApps 什么是Back to Back Order?
    三方贸易-drop ship
    Oracle Order Management DropShip Flow for R12
    OracleApps Dropship 流程
    geetoo编译安装
  • 原文地址:https://www.cnblogs.com/liang2713020/p/3597971.html
Copyright © 2020-2023  润新知