自己动手用Lazarus做的一个小DEMO,主要是验证CRC校验方法编写的与否。经验证没问题,其完整的程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 |
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); const
WordLength =6; //定义待校验字符串长度 var Data:array[0..255] of Byte; i,j:Integer; Edit1temp: string ; Edit1Value: string ; CRCtemp: string ; Res :Word; begin Edit1temp := Edit1.Text; Edit1Value :=StringReplace(Edit1temp, ‘ ‘ , ‘‘ ,[rfReplaceAll]); //取到待校验字符串并去掉字符串中间的所有空格 if
Length(Edit1Value) = 12 then //判断输入的字符串数量是否符合要求 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); Edit2.Text:=RightStr(CRCtemp,2)+ ‘ ‘ +LeftStr(CRCtemp,2); //得到的CRC校验结果的高低位交换,再显示 end else showmessage( ‘输入错误,请输入12位数!‘ ); end; end. |
界面控件如下:
12位CRC校验_Delphi,布布扣,bubuko.com
原文:http://www.cnblogs.com/liang2713020/p/3597971.html