JHJ_BABY

导航

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.

 

posted on 2014-03-13 10:20  JHJ_BABY  阅读(957)  评论(0编辑  收藏  举报