Delphi 串口通讯源码

串口读写器介绍: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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

津津有味道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值