串口读写器介绍:https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-17663462238.11.22f8e728Vsc3IR&id=18645495882https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-17663462238.11.22f8e728Vsc3IR&id=18645495882
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SPComm, StdCtrls, Buttons,StrUtils, ComCtrls,Math, ExtCtrls,Clipbrd;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
ComboBox1: TComboBox;
ComboBox2: TComboBox;
ComboBox3: TComboBox;
BitBtn1: TBitBtn;
Comm1: TComm;
Label15: TLabel;
Label16: TLabel;
RichEdit13: TRichEdit;
UpDown11: TUpDown;
Timer3: TTimer;
Timer2: TTimer;
ListBox1: TListBox;
BitBtn5: TBitBtn;
RichEdit10: TRichEdit;
UpDown7: TUpDown;
Label4: TLabel;
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
BitBtn2: TBitBtn;
Edit3: TEdit;
BitBtn3: TBitBtn;
ComboBox4: TComboBox;
ComboBox5: TComboBox;
Edit1: TEdit;
BitBtn4: TBitBtn;
RichEdit3: TRichEdit;
BitBtn6: TBitBtn;
Edit2: TEdit;
BitBtn8: TBitBtn;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
ComboBox6: TComboBox;
BitBtn9: TBitBtn;
ComboBox8: TComboBox;
Edit7: TEdit;
Label5: TLabel;
UpDown1: TUpDown;
RichEdit1: TRichEdit;
Label6: TLabel;
Label7: TLabel;
RichEdit2: TRichEdit;
UpDown2: TUpDown;
BitBtn10: TBitBtn;
RichEdit4: TRichEdit;
BitBtn7: TBitBtn;
Edit8: TEdit;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
RadioButton3: TRadioButton;
RadioButton4: TRadioButton;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn5Click(Sender: TObject);
procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
procedure BitBtn4Click(Sender: TObject);
procedure BitBtn6Click(Sender: TObject);
procedure BitBtn7Click(Sender: TObject);
procedure BitBtn8Click(Sender: TObject);
procedure BitBtn9Click(Sender: TObject);
procedure BitBtn10Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
FuncCode:integer;//串口指令的功能代码
issendwaitrev1:Boolean;
sendwaitrevsize:Integer;
sendwaitData: array[0..100] of Byte;
S70Page:byte; //s70扇区号
S70block:byte; //S70绝对块地址
S70buffdata: array[0..300] of Byte; //S70数据缓冲
S70buffp:Integer; //s70数据指针
wstr:string; //写卡数据
dispstr:string;
cardno10:string;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
i:Integer;
count:Integer;
begin
dispstr:='';
count := 0;
for i := 0 to 20 do //开发环境调试时,请关闭菜单栏 Tool/Debugger Options/integrated debugging 选项
begin
Comm1.CommName:='\\.\COM' + IntToStr(i);
try
Comm1.StartComm; //打开串口
Comm1.StopComm; //打开串口
ComboBox1.Items.Add('COM' + IntToStr(i));
count := count + 1;
except
end;
if(count>0) then
begin
ComboBox1.ItemIndex:=count-1;
end;
ComboBox4.ItemIndex:=1;
ComboBox5.ItemIndex:=1;
ComboBox6.ItemIndex:=2;
ComboBox8.ItemIndex:=0;
end;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if(BitBtn1.Caption = '打开串口') then
begin
try
Comm1.CommName:='\\.\'+ComboBox1.Text;
//以下代码一定要复制过去
Comm1.BaudRate:=strtoint(ComboBox2.text); //19200;
Comm1.ByteSize:=_8;
Comm1.ParityCheck:=False;
case combobox3.ItemIndex of
0: Comm1.Parity:=None;
1: Comm1.Parity:=Odd;
2: Comm1.Parity:=Even;
3: Comm1.Parity:=Mark;
else
Comm1.Parity:=Space;
end;
Comm1.StopBits:=_1;
Comm1.XoffChar:='#';
comm1.ReadIntervalTimeout:= StrToInt(RichEdit13.Lines[0]);
Comm1.StartComm; //打开串口
BitBtn1.Caption := '关闭串口';
ComboBox1.Enabled:=False;
except
ShowMessage('打开端口失败!');
end;
end
else
begin
try
timer2.Enabled :=false;
Comm1.StopComm; //关闭串口
BitBtn1.Caption := '打开串口';
ComboBox1.Enabled:=True;
except
end;
end;
end;
procedure TForm1.BitBtn5Click(Sender: TObject);
var
sendd:array[0..4]of Byte; //发送字节缓冲
SendDataStr:string;
delaytime:byte;
i:integer;
begin
if(BitBtn1.Caption <> '关闭串口') then
begin
Application.MessageBox('请先打开串口再进行修改在线设备站号的操作!', '警告', MB_OK+MB_ICONSTOP);
Exit;
end;
delaytime:=StrToInt(RichEdit10.Lines[0]);
sendd[0] := $03; //指令长度
sendd[1] := $0F; //指令代码
sendd[2] := delaytime mod 256;
sendd[3] := (delaytime div 256) mod 256;
sendd[4] := sendd[1] xor sendd[2] xor sendd[3];
FuncCode:=0; //驱动在线站号发声
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 5);
SendDataStr:='串口发送数据:';
for i:=0 to 4 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
end;
procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
i,para:integer;
answ:integer;
GetdataStr:string;
SendDataStr:string;
cardhao:Longword;
strls1,cardhaoStr:string;
CRC:byte;
sendd:array[0..20]of Byte; //发送字节缓冲
begin
GetdataStr:='串口接收数据:';
if issendwaitrev1 then
begin//在有发送指令等待返回
issendwaitrev1 := False;
sendwaitrevsize := BufferLength;
move(Buffer^,pchar(@(sendwaitData[0]))^,BufferLength);
for i:=0 to BufferLength-1 do
begin
GetdataStr:=GetdataStr+inttohex(sendwaitData[i],2)+' ';
if i=32 then
begin
ListBox1.Items.Add(GetdataStr);
listbox1.ItemIndex:=listbox1.Count-1;
GetdataStr:=' ' ;
end;
end;
if length(trim(GetdataStr))>0 then
begin
ListBox1.Items.Add(GetdataStr);
listbox1.ItemIndex:=listbox1.Count-1;
end;
crc:=0;
for i:=1 to BufferLength-1 do
begin
crc:=crc xor sendwaitData[i];
end;
if crc=0 then
begin
case FuncCode of
1,2,3,4:
begin
if (sendwaitData[0]=1) then
begin
case sendwaitData[1] of
1:
edit3.Text :='密码认证成功,卡片序列号已知,但读取扇区内容失败!';
2:
edit3.Text :='第0块读出,但第1、2块没读出,仅扇区内容前16个字节的数据有效!';
3:
edit3.Text :='第0、1块读出,但第2块没读出,仅扇区内容前32个字节的数据有效!';
8:
edit3.Text :='未寻到卡!';
9:
edit3.Text :='两张以上卡片同时在感应区,发生冲突!';
10:
edit3.Text :='无法选择激活卡片!';
11:
edit3.Text :='密码装载失败,卡片序列号已知!';
12:
edit3.Text :='密码认证失败,卡片序列号已知!';
end;
end
else
begin
if (sendwaitData[0]=5) then
begin
cardhao := sendwaitData[5] + sendwaitData[4]*256 + sendwaitData[3]*256*256 + sendwaitData[2]*256*256*256;
case sendwaitData[1] of
0:
begin
if FuncCode=2 then
strls1:='读卡成功 '
else if FuncCode=3 then
begin
if (S70Page>31) and (S70block<15) then
begin
dispstr:='S70卡 物理卡号:'+inttohex(sendwaitData[2],2)+'-'+inttohex(sendwaitData[3],2)+'-'+inttohex(sendwaitData[4],2)+'-'+inttohex(sendwaitData[5],2);
sendd[0]:=$12;
sendd[1]:=$A5;
sendd[2]:=128+(S70Page-32)*16+S70block;
crc:=sendd[1] xor sendd[2];
for i:=0 to 15 do
begin
sendd[3+i]:=strtoint('$'+midstr(wstr,S70buffp*2-1,2));
crc:=crc xor sendd[3+i];
S70buffp:=S70buffp+1;
end;
sendd[3+16]:=crc;
FuncCode:=8; //写S70的大扇区
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 20);
SendDataStr:='串口发送数据:';
for i:=0 to 19 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
S70block:=S70block+1;
end
else
strls1:='写卡成功 ';
end
else if FuncCode=4 then strls1:='更改密码成功 ' ;
end;
1:
strls1:='密码认证成功,卡片序列号已知,但读取扇区内容失败!';
2:
strls1:='第0块读出,但第1、2块没读出,仅扇区内容前16个字节的数据有效!';
3:
strls1:='第0、1块读出,但第2块没读出,仅扇区内容前32个字节的数据有效!';
8:
strls1:='未寻到卡!';
9:
strls1:='两张以上卡片同时在感应区,发生冲突!';
10:
strls1:='无法选择激活卡片!';
11:
strls1:='密码装载失败,卡片序列号已知!';
12:
strls1:='密码认证失败,卡片序列号已知!';
end;
strls1:=strls1+'物理卡号:'+inttohex(sendwaitData[2],2)+'-'+inttohex(sendwaitData[3],2)+'-'+inttohex(sendwaitData[4],2)+'-'+inttohex(sendwaitData[5],2);
strls1:=strls1+' 换算成十位卡号:'+ RightStr('000000000' + IntToStr(cardhao),10);
edit3.Text :=strls1;
end
else
begin
if (sendwaitData[0]=53) then
begin
cardhao := sendwaitData[5] + sendwaitData[4]*256 + sendwaitData[3]*256*256 + sendwaitData[2]*256*256*256;
strls1:='物理卡号:'+inttohex(sendwaitData[2],2)+'-'+inttohex(sendwaitData[3],2)+'-'+inttohex(sendwaitData[4],2)+'-'+inttohex(sendwaitData[5],2);
strls1:=strls1+' 换算成十位卡号:'+ RightStr('000000000' + IntToStr(cardhao),10);
edit3.Text :=strls1;
if (S70Page>31) and (S70block<15) then
begin
for i:=6 to BufferLength-2 do
begin
S70buffdata[S70buffp]:= sendwaitData[i];
S70buffp:=S70buffp+1;
end;
sendd[0]:=$02;
sendd[1]:=$B4;
sendd[2]:=128+(S70Page-32)*16+S70block;
sendd[3] := sendd[1] xor sendd[2];
FuncCode:=7; //读S70的大扇区
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 4);
SendDataStr:='串口发送数据:';
for i:=0 to 3 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
S70block:=S70block+1;
end
else
begin
GetdataStr:='';
for i:=6 to BufferLength-2 do
begin
GetdataStr:=GetdataStr+inttohex(sendwaitData[i],2)+' ';
end;
RichEdit3.Text :=GetdataStr;
end;
end
else
begin
if (sendwaitData[0]=54) then
begin
cardhao := sendwaitData[5] + sendwaitData[4]*256 + sendwaitData[3]*256*256 + sendwaitData[2]*256*256*256;
strls1:='物理卡号:'+inttohex(sendwaitData[2],2)+'-'+inttohex(sendwaitData[3],2)+'-'+inttohex(sendwaitData[4],2)+'-'+inttohex(sendwaitData[5],2);
strls1:=strls1+' 换算成十位卡号:'+ RightStr('000000000' + IntToStr(cardhao),10);
edit3.Text :=strls1;
if (S70Page>31) and (S70block<15) then
begin
for i:=7 to BufferLength-2 do
begin
S70buffdata[S70buffp]:= sendwaitData[i];
S70buffp:=S70buffp+1;
end;
sendd[0]:=$02;
sendd[1]:=$B4;
sendd[2]:=128+(S70Page-32)*16+S70block;
sendd[3] := sendd[1] xor sendd[2];
FuncCode:=7; //读S70的大扇区
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 4);
SendDataStr:='串口发送数据:';
for i:=0 to 3 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
S70block:=S70block+1;
end
else
begin
GetdataStr:='';
for i:=7 to BufferLength-2 do
begin
GetdataStr:=GetdataStr+inttohex(sendwaitData[i],2)+' ';
end;
RichEdit3.Text :=GetdataStr;
end;
end;
end;
end;
end;
end;
5:
begin
case sendwaitData[1] of
0:
begin
cardhaoStr:=inttohex(sendwaitData[2],2)+inttohex(sendwaitData[3],2)+inttohex(sendwaitData[4],2)+inttohex(sendwaitData[5],2)+inttohex(sendwaitData[6],2)+inttohex(sendwaitData[7],2)+inttohex(sendwaitData[8],2);
strls1:='读物理卡号:'+cardhaoStr+' 起始页:'+inttostr(sendwaitData[9])+',总计页数:'+inttostr(sendwaitData[10])+',数据读取成功!';
edit8.Text := strls1;
GetdataStr:='';
for i:=11 to BufferLength-2 do
begin
GetdataStr:=GetdataStr+inttohex(sendwaitData[i],2)+' ';
end;
RichEdit4.Text :=GetdataStr;
end;
8:
edit8.Text :='未寻到卡!';
9:
edit8.Text :='两张以上卡片同时在感应区,发生冲突!';
12:
begin
cardhaoStr:=inttohex(sendwaitData[2],2)+inttohex(sendwaitData[3],2)+inttohex(sendwaitData[4],2)+inttohex(sendwaitData[5],2)+inttohex(sendwaitData[6],2)+inttohex(sendwaitData[7],2)+inttohex(sendwaitData[8],2);
edit8.Text :='密码认证失败,卡片序列号:'+cardhaoStr;
end;
13:
begin
cardhaoStr:=inttohex(sendwaitData[2],2)+inttohex(sendwaitData[3],2)+inttohex(sendwaitData[4],2)+inttohex(sendwaitData[5],2)+inttohex(sendwaitData[6],2)+inttohex(sendwaitData[7],2)+inttohex(sendwaitData[8],2);
edit8.Text :='密码认证失败,读取页内容失败!卡片序列号:'+cardhaoStr;
end;
else
edit8.Text :='读卡错误,返回代码:'+inttostr(sendwaitData[1]);
end;
end;
6:
begin
case sendwaitData[1] of
0:
begin
cardhaoStr:=inttohex(sendwaitData[2],2)+inttohex(sendwaitData[3],2)+inttohex(sendwaitData[4],2)+inttohex(sendwaitData[5],2)+inttohex(sendwaitData[6],2)+inttohex(sendwaitData[7],2)+inttohex(sendwaitData[8],2);
strls1:='写物理卡号:'+cardhaoStr+' 成功!';
edit8.Text := strls1;
end;
8:
edit8.Text :='未寻到卡!';
9:
edit8.Text :='两张以上卡片同时在感应区,发生冲突!';
12:
begin
cardhaoStr:=inttohex(sendwaitData[2],2)+inttohex(sendwaitData[3],2)+inttohex(sendwaitData[4],2)+inttohex(sendwaitData[5],2)+inttohex(sendwaitData[6],2)+inttohex(sendwaitData[7],2)+inttohex(sendwaitData[8],2);
edit8.Text :='密码认证失败,卡片序列号:'+cardhaoStr;
end;
else
edit8.Text :='写卡错误,返回代码:'+inttostr(sendwaitData[1]);
end;
end;
7:
begin
for i:=2 to BufferLength-2 do
begin
S70buffdata[S70buffp]:= sendwaitData[i];
S70buffp:=S70buffp+1;
end;
if S70block>14 then
begin
GetdataStr:='';
for i:=0 to S70buffp-1 do
begin
GetdataStr:=GetdataStr+inttohex(S70buffdata[i],2)+' ';
end;
RichEdit3.Text :=GetdataStr;
end;
if S70block<15 then
begin
sendd[0]:=$02;
sendd[1]:=$B4;
sendd[2]:=128+(S70Page-32)*16+S70block;
sendd[3] := sendd[1] xor sendd[2];
FuncCode:=7; //读S70的大扇区
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 4);
SendDataStr:='串口发送数据:';
for i:=0 to 3 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
S70block:=S70block+1;
end;
end;
8:
begin
if sendwaitData[1]=0 then
begin
if (S70Page>31) and (S70block<15) then
begin
sendd[0]:=$12;
sendd[1]:=$A5;
sendd[2]:=128+(S70Page-32)*16+S70block;
crc:=sendd[1] xor sendd[2];
for i:=0 to 15 do
begin
sendd[3+i]:=strtoint('$'+midstr(wstr,S70buffp*2-1,2));
crc:=crc xor sendd[3+i];
S70buffp:=S70buffp+1;
end;
sendd[3+16]:=crc;
FuncCode:=8; //写S70的大扇区
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 20);
SendDataStr:='串口发送数据:';
for i:=0 to 19 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
S70block:=S70block+1;
end
else
edit3.Text:=dispstr+' 写卡成功 ';
end
else
begin
edit3.Text:=dispstr+' 写卡失败 ';
end;
end;
end;
end;
end;
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
var
sendd:array[0..2]of Byte; //发送字节缓冲
SendDataStr:string;
i:integer;
begin
if(BitBtn1.Caption <> '关闭串口') then
begin
Application.MessageBox('请先打开串口再进行修改在线设备站号的操作!', '警告', MB_OK+MB_ICONSTOP);
Exit;
end;
sendd[0] := $01;
sendd[1] := $F0;
sendd[2] := $F0;
FuncCode:=1; //驱动读卡序列号
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 3);
SendDataStr:='串口发送数据:';
for i:=0 to 2 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
end;
procedure TForm1.BitBtn3Click(Sender: TObject);
var
sendd:array[0..15]of Byte; //发送字节缓冲
SendDataStr,wstr:string;
CRC:byte;
i:integer;
begin
if(BitBtn1.Caption <> '关闭串口') then
begin
Application.MessageBox('请先打开串口再进行修改在线设备站号的操作!', '警告', MB_OK+MB_ICONSTOP);
Exit;
end;
RichEdit3.Text :='';
sendd[0] := $0E;
sendd[1] := $78;
sendd[2] := $17;
sendd[3] := $0;
sendd[4] := $0;
sendd[5] := $0;
sendd[6] := $0;
sendd[7] := ComboBox4.ItemIndex; //区号
sendd[8] := ComboBox5.ItemIndex; //A/B
wstr:=trim(edit1.Text)+'FFFFFFFFFFFF';
for i:=0 to 5 do
begin
sendd[9+i]:=strtoint('$'+midstr(wstr,i*2+1,2));
end;
CRC:=0;
FOR I:=1 TO 14 DO
BEGIN
CRC:=CRC XOR sendd[I];
END;
sendd[15] := CRC;
FuncCode:=2; //驱动读卡
issendwaitrev1 := True;
sendwaitrevsize := 0;
S70block:=3;
S70Page:=ComboBox4.ItemIndex;
S70buffp:=0;
Comm1.WriteCommData(@sendd[0], 16);
SendDataStr:='串口发送数据:';
for i:=0 to 15 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
end;
procedure TForm1.BitBtn4Click(Sender: TObject);
var
sendd:array[0..63]of Byte; //发送字节缓冲
SendDataStr:string;
CRC:byte;
i:integer;
begin
if(BitBtn1.Caption <> '关闭串口') then
begin
Application.MessageBox('请先打开串口再进行修改在线设备站号的操作!', '警告', MB_OK+MB_ICONSTOP);
Exit;
end;
sendd[0] := $3E;
sendd[1] := $69;
sendd[2] := $17;
sendd[3] := $0;
sendd[4] := $0;
sendd[5] := $0;
sendd[6] := $0;
sendd[7] := ComboBox4.ItemIndex; //区号
sendd[8] := ComboBox5.ItemIndex; //A/B
wstr:=trim(edit1.Text)+'FFFFFFFFFFFF';
for i:=0 to 5 do
begin
sendd[9+i]:=strtoint('$'+midstr(wstr,i*2+1,2));
end;
wstr:='';
if length(trim(RichEdit3.Lines[0]))>0 then wstr:=wstr+trim(RichEdit3.Lines[0]);
if length(trim(RichEdit3.Lines[1]))>0 then wstr:=wstr+' '+trim(RichEdit3.Lines[1]);
if length(trim(RichEdit3.Lines[2]))>0 then wstr:=wstr+' '+trim(RichEdit3.Lines[2]);
if length(trim(RichEdit3.Lines[3]))>0 then wstr:=wstr+' '+trim(RichEdit3.Lines[3]);
if length(trim(RichEdit3.Lines[4]))>0 then wstr:=wstr+' '+trim(RichEdit3.Lines[4]);
if length(trim(RichEdit3.Lines[5]))>0 then wstr:=wstr+' '+trim(RichEdit3.Lines[5]);
if length(trim(RichEdit3.Lines[6]))>0 then wstr:=wstr+' '+trim(RichEdit3.Lines[6]);
if length(trim(RichEdit3.Lines[7]))>0 then wstr:=wstr+' '+trim(RichEdit3.Lines[7]);
for i:=0 to 255 do //写入数据不足后面补0
begin
if RadioButton1.Checked then wstr:=wstr+'00' else wstr:=wstr+inttohex(i,2); //按顺序写入数字
end;
wstr:=StringReplace(wstr, chr(32), '', [rfReplaceAll]);//删除空格
for i:=1 to 48 do
begin
sendd[14+i]:=strtoint('$'+midstr(wstr,i*2-1,2));
end;
CRC:=0;
FOR I:=1 TO 62 DO
BEGIN
CRC:=CRC XOR sendd[I];
END;
sendd[63] := CRC;
FuncCode:=3; //驱动写卡
issendwaitrev1 := True;
sendwaitrevsize := 0;
S70buffp:=49;
S70block:=3;
S70Page:=ComboBox4.ItemIndex;
dispstr:='';
Comm1.WriteCommData(@sendd[0], 64);
SendDataStr:='串口发送数据:';
for i:=0 to 63 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
if i=32 then
begin
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
SendDataStr:=' ' ;
end;
end;
if length(trim(SendDataStr))>0 then
begin
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
end;
end;
procedure TForm1.BitBtn6Click(Sender: TObject);
var
sendd:array[0..21]of Byte; //发送字节缓冲
SendDataStr,wstr:string;
CRC:byte;
i:integer;
begin
if(BitBtn1.Caption <> '关闭串口') then
begin
Application.MessageBox('请先打开串口再进行修改在线设备站号的操作!', '警告', MB_OK+MB_ICONSTOP);
Exit;
end;
RichEdit3.Text :='';
sendd[0] := $14;
sendd[1] := $3C;
sendd[2] := $17;
sendd[3] := $0;
sendd[4] := $0;
sendd[5] := $0;
sendd[6] := $0;
sendd[7] := ComboBox4.ItemIndex; //区号
sendd[8] := ComboBox5.ItemIndex; //A/B
wstr:=trim(edit1.Text)+'FFFFFFFFFFFF'; //旧密码
for i:=0 to 5 do
begin
sendd[9+i]:=strtoint('$'+midstr(wstr,i*2+1,2));
end;
wstr:=trim(edit2.Text)+'FFFFFFFFFFFF'; //新密码
for i:=0 to 5 do
begin
sendd[15+i]:=strtoint('$'+midstr(wstr,i*2+1,2));
end;
CRC:=0;
FOR I:=1 TO 20 DO
BEGIN
CRC:=CRC XOR sendd[I];
END;
sendd[21] := CRC;
FuncCode:=4; //驱动更改卡密码
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 22);
SendDataStr:='串口发送数据:';
for i:=0 to 21 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
end;
procedure TForm1.BitBtn7Click(Sender: TObject);
begin
ListBox1.Clear();
end;
procedure TForm1.BitBtn8Click(Sender: TObject);
var
sendd:array[0..32]of Byte; //发送字节缓冲
SendDataStr,wstr:string;
CRC:byte;
i:integer;
begin
if(BitBtn1.Caption <> '关闭串口') then
begin
Application.MessageBox('请先打开串口再进行修改在线设备站号的操作!', '警告', MB_OK+MB_ICONSTOP);
Exit;
end;
if MessageDlg('错误的参数将会损坏卡片,确定要修改密码及控制字吗?', mtWarning, mbOKCancel, 0) <> mrOk then
begin
exit;
end;
RichEdit3.Text :='';
sendd[0] := $1F;
sendd[1] := $F1;
sendd[2] := $17;
sendd[3] := $0;
sendd[4] := $0;
sendd[5] := $0;
sendd[6] := $0;
sendd[7] := ComboBox4.ItemIndex; //区号
sendd[8] := ComboBox5.ItemIndex; //A/B
wstr:=trim(edit1.Text)+'FFFFFFFFFFFF'; //旧密码
for i:=0 to 5 do
begin
sendd[9+i]:=strtoint('$'+midstr(wstr,i*2+1,2));
end;
wstr:=trim(edit4.Text)+'FFFFFFFFFFFF'; //新A密码
for i:=0 to 5 do
begin
sendd[15+i]:=strtoint('$'+midstr(wstr,i*2+1,2));
end;
wstr:=trim(edit5.Text)+'FF078069'; //控制字
for i:=0 to 3 do
begin
sendd[21+i]:=strtoint('$'+midstr(wstr,i*2+1,2));
end;
wstr:=trim(edit6.Text)+'FFFFFFFFFFFF'; //新B密码
for i:=0 to 5 do
begin
sendd[25+i]:=strtoint('$'+midstr(wstr,i*2+1,2));
end;
sendd[31]:= ComboBox6.ItemIndex; //控制字
if sendd[31]>1 then sendd[31]:=3;
CRC:=0;
FOR I:=1 TO 31 DO
BEGIN
CRC:=CRC XOR sendd[I];
END;
sendd[32] := CRC;
FuncCode:=4; //驱动更改卡密码
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 33);
SendDataStr:='串口发送数据:';
for i:=0 to 32 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
end;
procedure TForm1.BitBtn9Click(Sender: TObject);
var
sendd:array[0..16]of Byte; //发送字节缓冲
SendDataStr,wstr:string;
CRC:byte;
i:integer;
begin
if(BitBtn1.Caption <> '关闭串口') then
begin
Application.MessageBox('请先打开串口再进行修改在线设备站号的操作!', '警告', MB_OK+MB_ICONSTOP);
Exit;
end;
Edit8.Text :='';
RichEdit4.Text :='';
sendd[0] := $0F; //帧长度
sendd[1] := $1B; //命令字
if ComboBox8.ItemIndex=0 then
sendd[2] := $00 //控制字 0 表示无需密码操作任意卡; +8 表示指定卡;+16表示 带密码操作
else
sendd[2] := $10; //控制字 $10 表示带密码操作
sendd[3] := $0; //指定7个字节要操作的卡号,如7字节全部取0表示可以操作任意卡
sendd[4] := $0;
sendd[5] := $0;
sendd[6] := $0;
sendd[7] := $0;
sendd[8] := $0;
sendd[9] := $0;
wstr:=trim(edit7.Text)+'00000000';
for i:=0 to 3 do
begin
sendd[10+i]:=strtoint('$'+midstr(wstr,i*2+1,2));
end;
sendd[14] := StrToInt(RichEdit1.Lines[0]);
sendd[15] := StrToInt(RichEdit2.Lines[0]);
CRC:=0;
FOR I:=1 TO 15 DO
BEGIN
CRC:=CRC XOR sendd[I];
END;
sendd[16] := CRC;
FuncCode:=5; //驱动读Ntag21x
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 17);
SendDataStr:='串口发送数据:';
for i:=0 to 16 do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
end;
procedure TForm1.BitBtn10Click(Sender: TObject);
var
sendd:array[0..100]of Byte; //发送字节缓冲
SendDataStr,wstr,pstr:string;
CRC:byte;
i,wlen:integer;
begin
if(BitBtn1.Caption <> '关闭串口') then
begin
Application.MessageBox('请先打开串口再进行修改在线设备站号的操作!', '警告', MB_OK+MB_ICONSTOP);
Exit;
end;
if StrToInt(RichEdit2.Lines[0])>11 then
begin
Application.MessageBox('每次写卡最多只能连写11个页!', '警告', MB_OK+MB_ICONSTOP);
Exit;
end;
Edit8.Text :='';
wlen:=StrToInt(RichEdit2.Lines[0])*4;
wstr:='';
if length(trim(RichEdit4.Lines[0]))>0 then wstr:=wstr+trim(RichEdit4.Lines[0]);
if length(trim(RichEdit4.Lines[1]))>0 then wstr:=wstr+trim(RichEdit4.Lines[1]);
wstr:=StringReplace(wstr, chr(32), '', [rfReplaceAll]);//删除空格
if length(wstr)< wlen*2-1 then
begin
if MessageDlg('写卡数据不足,是否要按条件补足写入?', mtWarning, mbOKCancel, 0) <> mrOk then
begin
exit;
end;
end;
for i:=0 to 47 do
begin
if RadioButton3.Checked then wstr:=wstr+'00' else wstr:=wstr+inttohex(i,2); //按顺序写入数字
end;
sendd[0] := 15+wlen; //帧长度
sendd[1] := $1C; //命令字
if ComboBox8.ItemIndex=0 then
sendd[2] := $00 //控制字 0 表示无需密码操作任意卡; +8 表示指定卡;+16表示 带密码操作
else
sendd[2] := $10; //控制字 $10 表示带密码操作
sendd[3] := $0; //指定7个字节要操作的卡号,如7字节全部取0表示可以操作任意卡
sendd[4] := $0;
sendd[5] := $0;
sendd[6] := $0;
sendd[7] := $0;
sendd[8] := $0;
sendd[9] := $0;
pstr:=trim(edit7.Text)+'00000000';
for i:=0 to 3 do
begin
sendd[10+i]:=strtoint('$'+midstr(pstr,i*2+1,2));
end;
sendd[14] := StrToInt(RichEdit1.Lines[0]);
sendd[15] := StrToInt(RichEdit2.Lines[0]);
try
for i:=1 to wlen do
begin
sendd[15+i]:=strtoint('$'+midstr(wstr,i*2-1,2));
end;
except
begin
Application.MessageBox('写卡数据异常!', '警告', MB_OK+MB_ICONSTOP);
Exit;
end;
end;
CRC:=0;
FOR I:=1 TO 15+wlen DO
BEGIN
CRC:=CRC XOR sendd[I];
END;
sendd[16+wlen] := CRC;
FuncCode:=6; //驱动写Ntag21x
issendwaitrev1 := True;
sendwaitrevsize := 0;
Comm1.WriteCommData(@sendd[0], 17+wlen);
SendDataStr:='串口发送数据:';
for i:=0 to 16+wlen do
begin
SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';
end;
ListBox1.Items.Add(SendDataStr);
listbox1.ItemIndex:=listbox1.Count-1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
liststr:string;
i:integer;
begin
liststr:='';
for i:=0 to listbox1.Count-1 do
begin
ListBox1.ItemIndex:=i;
liststr:=liststr+ListBox1.Items.Strings[ListBox1.ItemIndex]+#13#10;
end;
Clipboard.SetTextBuf(PChar(liststr));
end;
end.
项目源码及控件下载:
Delph_Spcomm_NFC串口读写器源码-智慧城市文档类资源-CSDN下载Delphi7使用串口通讯控件SPcomm,连接RFID、NFC串口发卡器读、写M1、S50、S70更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/zhangjin7422/85358751