Modbus协议CRC的两种算法源码

Modbus协议CRC的两种Delphi算法源码举例。在工控开发时经常用到.原文http://www.tansoo.cn/?p=48

unit Unit1;     

interface     

uses     
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;     

type     
  TDataByte = array of byte;     

  TForm1 = class(TForm)     
    Button1: TButton;     
    Edit1: TEdit;     
    Label1: TLabel;     
    Edit2: TEdit;     
    procedure Button1Click(Sender: TObject);     
  private     
    { Private declarations }     
  public     
    { Public declarations }     
  end;     

const     
  CRCHi: array [0..255] of byte =     
(     
$00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41, $00,     
$C1, $81, $40, $01, $C0, $80, $41, $00, $C1, $81, $40, $00, $C1,     
$81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81,     
$40, $00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1, $81, $40,     
$01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, $01,     
$C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0,     
$80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, $80,     
$41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41,     
$01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, $00,     
$C1, $81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0,     
$80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, $80,     
$41, $00, $C1, $81, $40, $01, $C0, $80, $41, $01, $C0, $80, $41,     
$00, $C1, $81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, $01,     
$C0, $80, $41, $00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1,     
$81, $40, $00, $C1, $81, $40, $01, $C0, $80, $41, $00, $C1, $81,     
$40, $01, $C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40,     
$01, $C0, $80, $41, $00, $C1, $81, $40, $00, $C1, $81, $40, $01,     
$C0, $80, $41, $01, $C0, $80, $41, $00, $C1, $81, $40, $00, $C1,     
$81, $40, $01, $C0, $80, $41, $00, $C1, $81, $40, $01, $C0, $80,     
$41, $01, $C0, $80, $41, $00, $C1, $81, $40     
) ;     

CRCLo: array [0..255] of  byte =     
(     
$00, $C0, $C1, $01, $C3, $03, $02, $C2, $C6, $06, $07, $C7, $05,     
$C5, $C4, $04, $CC, $0C, $0D, $CD, $0F, $CF, $CE, $0E, $0A, $CA,     
$CB, $0B, $C9, $09, $08, $C8, $D8, $18, $19, $D9, $1B, $DB, $DA,     
$1A, $1E, $DE, $DF, $1F, $DD, $1D, $1C, $DC, $14, $D4, $D5, $15,     
$D7, $17, $16, $D6, $D2, $12, $13, $D3, $11, $D1, $D0, $10, $F0,     
$30, $31, $F1, $33, $F3, $F2, $32, $36, $F6, $F7, $37, $F5, $35,     
$34, $F4, $3C, $FC, $FD, $3D, $FF, $3F, $3E, $FE, $FA, $3A, $3B,     
$FB, $39, $F9, $F8, $38, $28, $E8, $E9, $29, $EB, $2B, $2A, $EA,     
$EE, $2E, $2F, $EF, $2D, $ED, $EC, $2C, $E4, $24, $25, $E5, $27,     
$E7, $E6, $26, $22, $E2, $E3, $23, $E1, $21, $20, $E0, $A0, $60,     
$61, $A1, $63, $A3, $A2, $62, $66, $A6, $A7, $67, $A5, $65, $64,     
$A4, $6C, $AC, $AD, $6D, $AF, $6F, $6E, $AE, $AA, $6A, $6B, $AB,     
$69, $A9, $A8, $68, $78, $B8, $B9, $79, $BB, $7B, $7A, $BA, $BE,     
$7E, $7F, $BF, $7D, $BD, $BC, $7C, $B4, $74, $75, $B5, $77, $B7,     
$B6, $76, $72, $B2, $B3, $73, $B1, $71, $70, $B0, $50, $90, $91,     
$51, $93, $53, $52, $92, $96, $56, $57, $97, $55, $95, $94, $54,     
$9C, $5C, $5D, $9D, $5F, $9F, $9E, $5E, $5A, $9A, $9B, $5B, $99,     
$59, $58, $98, $88, $48, $49, $89, $4B, $8B, $8A, $4A, $4E, $8E,     
$8F, $4F, $8D, $4D, $4C, $8C, $44, $84, $85, $45, $87, $47, $46,     
$86, $82, $42, $43, $83, $41, $81, $80, $40     
);     

var     
  Form1: TForm1;     

implementation     

{$R *.dfm}     

function crc16(var dataaddress :byte; datalength: byte): word;     
var     
  hi: byte;     
  lo: byte;     
  i: byte;     
  index: byte;     
  datadd: pbytearray;     
begin     
  hi := $FF;     
  lo := $FF;     
  datadd := @dataaddress;     
  i := 0;     
  while (datalength > 0) do     
  begin     
    index := hi xor datadd^;     
    i := i + 1;     
    hi := lo xor crchi[index];     
    lo := crclo[index];     
   datalength := datalength - 1;     
  end;     
  crc16 := hi shl 8 or lo;     
end;     

function ModBusCRC(Data: string): string; //生成modbus CRC数据     
var     
  CRC16Lo, CRC16Hi, CL, CH, UseHi, UseLo: Dword;     
  i, index: integer;     
begin     
  CRC16Lo := $FF; //CRC16Lo为CRC寄存器低8位     
  CRC16Hi := $FF; //CRC16Hi为CRC寄存器高8位     
  CL := $01;     
  CH := $A0; //  A001 H 是CRC-16多项式代码     
  for i := 1 to Length(Data) do     
  begin     
    CRC16Lo := CRC16Lo xor ord(Data[i]); //每一个数据与CRC寄存器异或     
    for index := 0 to 7 do     
    begin     
      UseHi := CRC16Hi;     
      UseLo := CRC16Lo;     
      CRC16Hi := CRC16Hi shr 1;     
      CRC16Lo := CRC16Lo shr 1; //右移一位     
      if ((UseHi and $1) = $1) then //如果高位字节最后一位是1的话     
        CRC16Lo := CRC16Lo or $80; //低位字节右移后前面补1     

      if ((UseLo and $1) = $1) then //如果LSB 为1,则与多项式进行异或     
      begin     
        CRC16Hi := CRC16Hi xor CH;     
        CRC16Lo := CRC16Lo xor CL;     
      end;     
    end;     
  end;     

  Result := IntToHex(CRC16Lo, 2) + IntToHex(CRC16Hi, 2);     
end;     

procedure TForm1.Button1Click(Sender: TObject);     
var     
  Data1 : TDataByte;     
  c:word;     
  i,l:integer;     
begin     
  l := Length(Edit1.Text);     
  Setlength(Data1,l);     
  for i:=0 to l-1 do     
    Data1[i]:= ord(Edit1.Text[i+1]);     

  c:=CRC16(Data1[0],l);     
  Edit2.Text:=('ModBusCRC='+ModBusCRC(Edit1.Text)+'     CRC16='+ inttohex(c,4));     
end;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值