POLY = $A001; function GetCRCValue(buff: array of byte; len: integer): word; var crc: word; i, j, xor_f: integer; begin crc := $FFFF; for i := 0 to len - 1 do begin CRC := (crc xor buff[i]); for j := 0 to 7 do begin xor_f:= (CRC and $01); CRC := (crc shr 1); if xor_f= 1 then begin CRC := crc xor POLY; end; end; end; result := crc; end;procedure N4Click(Sender: TObject); var s:array[0..0] of byte; begin s[0]:=1; showmessage(inttohex(GetCRCValue(s,1),4)); end;
下面是我用过的一个函数:function CRC(var Data: byte; Size: byte): Word; // 生成modbus CRC数据 var CRC16Lo, CRC16Hi, CL, CH, UseHi, UseLo: Dword; i, index: integer; DataAdder: PByteArray; begin CRC16Lo := $FF; // CRC16Lo为CRC寄存器低8位 CRC16Hi := $FF; // CRC16Hi为CRC寄存器高8位 CL := $01; CH := $A0; // A001 H 是CRC-16多项式代码 DataAdder := @Data; for i := 0 to Size - 1 do begin CRC16Lo := CRC16Lo xor DataAdder^[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 := (CRC16Hi shl 8) or CRC16Lo; end;
function GetCRCValue(buff: array of byte; len: integer): word;
var
crc: word;
i, j, xor_f: integer;
begin
crc := $FFFF;
for i := 0 to len - 1 do
begin
CRC := (crc xor buff[i]);
for j := 0 to 7 do
begin
xor_f:= (CRC and $01);
CRC := (crc shr 1);
if xor_f= 1 then
begin
CRC := crc xor POLY;
end;
end;
end;
result := crc;
end;procedure N4Click(Sender: TObject);
var
s:array[0..0] of byte;
begin
s[0]:=1;
showmessage(inttohex(GetCRCValue(s,1),4));
end;
var
CRC16Lo, CRC16Hi, CL, CH, UseHi, UseLo: Dword;
i, index: integer;
DataAdder: PByteArray;
begin
CRC16Lo := $FF; // CRC16Lo为CRC寄存器低8位
CRC16Hi := $FF; // CRC16Hi为CRC寄存器高8位
CL := $01;
CH := $A0; // A001 H 是CRC-16多项式代码
DataAdder := @Data;
for i := 0 to Size - 1 do
begin
CRC16Lo := CRC16Lo xor DataAdder^[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 := (CRC16Hi shl 8) or CRC16Lo;
end;
TMyCRC = record
Lowbyte: byte;
Highbyte: byte;
end;var
table16: array[0..255] of word =
(
$0000, $C1C0, $81C1, $4001, $01C3, $C003, $8002, $41C2,
$01C6, $C006, $8007, $41C7, $0005, $C1C5, $81C4, $4004,
$01CC, $C00C, $800D, $41CD, $000F, $C1CF, $81CE, $400E,
$000A, $C1CA, $81CB, $400B, $01C9, $C009, $8008, $41C8,
$01D8, $C018, $8019, $41D9, $001B, $C1DB, $81DA, $401A,
$001E, $C1DE, $81DF, $401F, $01DD, $C01D, $801C, $41DC,
$0014, $C1D4, $81D5, $4015, $01D7, $C017, $8016, $41D6,
$01D2, $C012, $8013, $41D3, $0011, $C1D1, $81D0, $4010,
$01F0, $C030, $8031, $41F1, $0033, $C1F3, $81F2, $4032,
$0036, $C1F6, $81F7, $4037, $01F5, $C035, $8034, $41F4,
$003C, $C1FC, $81FD, $403D, $01FF, $C03F, $803E, $41FE,
$01FA, $C03A, $803B, $41FB, $0039, $C1F9, $81F8, $4038,
$0028, $C1E8, $81E9, $4029, $01EB, $C02B, $802A, $41EA,
$01EE, $C02E, $802F, $41EF, $002D, $C1ED, $81EC, $402C,
$01E4, $C024, $8025, $41E5, $0027, $C1E7, $81E6, $4026,
$0022, $C1E2, $81E3, $4023, $01E1, $C021, $8020, $41E0,
$01A0, $C060, $8061, $41A1, $0063, $C1A3, $81A2, $4062,
$0066, $C1A6, $81A7, $4067, $01A5, $C065, $8064, $41A4,
$006C, $C1AC, $81AD, $406D, $01AF, $C06F, $806E, $41AE,
$01AA, $C06A, $806B, $41AB, $0069, $C1A9, $81A8, $4068,
$0078, $C1B8, $81B9, $4079, $01BB, $C07B, $807A, $41BA,
$01BE, $C07E, $807F, $41BF, $007D, $C1BD, $81BC, $407C,
$01B4, $C074, $8075, $41B5, $0077, $C1B7, $81B6, $4076,
$0072, $C1B2, $81B3, $4073, $01B1, $C071, $8070, $41B0,
$0050, $C190, $8191, $4051, $0193, $C053, $8052, $4192,
$0196, $C056, $8057, $4197, $0055, $C195, $8194, $4054,
$019C, $C05C, $805D, $419D, $005F, $C19F, $819E, $405E,
$005A, $C19A, $819B, $405B, $0199, $C059, $8058, $4198,
$0188, $C048, $8049, $4189, $004B, $C18B, $818A, $404A,
$004E, $C18E, $818F, $404F, $018D, $C04D, $804C, $418C,
$0044, $C184, $8185, $4045, $0187, $C047, $8046, $4186,
$0182, $C042, $8043, $4183, $0041, $C181, $8180, $4040
);function GetCRC16Code(InputBuff: PAnsichar; BuffLen: integer): string;
var
CRCvalue, CRCvalueH, CRCvalueL, Index: word;
i: integer;
begin
CRCvalueH := $FF;
CRCvalueL := $FF;
for i := 0 to BuffLen - 1 do
begin
Index := CRCvalueH xor byte(InputBuff[i]);
CRCvalueH := CRCvalueL xor byte(tableH[Index]);
CRCvalueL := tableL[Index];
end;
CRCvalue := CRCvalueL shl 8 + CRCvalueH; //低前高后
Result := IntTohex(CRCvalue, 4);
end;
tableH: array[0..255] of word =
(
$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
); tableL: array[0..255] of word =
(
$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
s:array[0..0] of byte;
CRCValue: string;
begin
s[0]:=$01;
CRCValue := GetCRC16Code(@S[0],1); //807E
end;