zoukankan      html  css  js  c++  java
  • 我的程序分析之路

    unit reader;      {这个是我标注的}
    {疑问:
    1.  curOrderNo curOperNo  orderLst  recDataLst 这些都是干什么的
    }
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ComCtrls, ExtCtrls, StdCtrls, SPComm;
    
    type                         //定义类
      TfrmReader = class(TForm)
        pnlTitle: TPanel;
        comReader: TComm;
        Label6: TLabel;
        Panel1: TPanel;
        pgcReader: TPageControl;
        tbsConfig: TTabSheet;
        gbCommSet: TGroupBox;
        lblComName: TLabel;
        lblBaudRate: TLabel;
        lblParity: TLabel;
        lblByteSize: TLabel;
        lblStopBits: TLabel;
        cbComName: TComboBox;
        cbBaudRate: TComboBox;
        cbParity: TComboBox;
        cbByteSize: TComboBox;
        cbStopBits: TComboBox;
        btnChComm: TButton;
        btnTestReader: TButton;
        memComSet: TMemo;
        edStatus: TEdit;
        TabSheet1: TTabSheet;
        GroupBox1: TGroupBox;
        Label1: TLabel;
        Label2: TLabel;
        Label3: TLabel;
        Label4: TLabel;
        Label5: TLabel;
        Label7: TLabel;
        ComboBox1: TComboBox;
        ComboBox2: TComboBox;
        ComboBox3: TComboBox;
        ComboBox4: TComboBox;
        ComboBox5: TComboBox;
        Button1: TButton;
        Button18: TButton;
        GroupBox16: TGroupBox;
        ComboBox20: TComboBox;
        tbsLowLevel: TTabSheet;
        gbLoweOper: TGroupBox;
        btnSeekCard: TButton;
        btnCollision: TButton;
        btnSelect: TButton;
        btnTerminate: TButton;
        gbLowRe: TGroupBox;
        memLowRe: TMemo;
        tbsPassDown: TTabSheet;
        gbPasswordDown: TGroupBox;
        lblPDSector0: TLabel;
        lblPDSector1: TLabel;
        lblPDSector2: TLabel;
        lblPDSector3: TLabel;
        lblPDSector4: TLabel;
        lblPDSector5: TLabel;
        lblPDSector6: TLabel;
        lblPDSector7: TLabel;
        lblPDSector8: TLabel;
        lblPDSector9: TLabel;
        lblPDSectorA: TLabel;
        lblPDSectorB: TLabel;
        lblPDSectorC: TLabel;
        lblPDSectorD: TLabel;
        lblPDSectorE: TLabel;
        lblPDSectorF: TLabel;
        edtSecPwd0: TEdit;
        edtSecPwd1: TEdit;
        edtSecPwd2: TEdit;
        edtSecPwd3: TEdit;
        edtSecPwd4: TEdit;
        edtSecPwd5: TEdit;
        edtSecPwd6: TEdit;
        edtSecPwd7: TEdit;
        edtSecPwd8: TEdit;
        edtSecPwd9: TEdit;
        edtSecPwd10: TEdit;
        edtSecPwd11: TEdit;
        edtSecPwd12: TEdit;
        edtSecPwd13: TEdit;
        edtSecPwd14: TEdit;
        edtSecPwd15: TEdit;
        rgSePwdOrg: TRadioGroup;
        btnPwdDwn: TButton;
        tbsDataOper: TTabSheet;
        gbRWSector: TGroupBox;
        lblBlock0: TLabel;
        lblBlock1: TLabel;
        lblBlock2: TLabel;
        lblBlock3: TLabel;
        edtBlock0: TEdit;
        edtBlock1: TEdit;
        edtBlock2: TEdit;
        edtBlock3: TEdit;
        gbRWSeSec: TGroupBox;
        cbRWSec: TComboBox;
        btnBlockRd: TButton;
        btnBlockWt: TButton;
        tbsBlockOper: TTabSheet;
        gbReOrWt: TGroupBox;
        lblCurValue: TLabel;
        lblOpeValue: TLabel;
        edtCurValue: TEdit;
        edtOpeValue: TEdit;
        gbBkSec: TGroupBox;
        cbBSecSe: TComboBox;
        gbBlokSe: TGroupBox;
        cbBSe: TComboBox;
        btnBlockInit: TButton;
        btnBlockRead: TButton;
        btnBlockAdd: TButton;
        btnBlockSub: TButton;
        tbsPassCh: TTabSheet;
        gbEntryPwd: TGroupBox;
        lblPwdA: TLabel;
        lblPwdB: TLabel;
        edtPwdA: TEdit;
        edtPwdB: TEdit;
        gbConBit: TGroupBox;
        lblConBit0: TLabel;
        lblConBit1: TLabel;
        lblConBit2: TLabel;
        lblConBit3: TLabel;
        edtConBit0: TEdit;
        edtConBit1: TEdit;
        edtConBit2: TEdit;
        edtConBit3: TEdit;
        gbChPwdSec: TGroupBox;
        cbChPwdSec: TComboBox;
        btnChPwd: TButton;
        btnChCon: TButton;
        tbsSeRe: TTabSheet;
        gbComSendRec: TGroupBox;
        lblExplain: TLabel;
        memComSeRe: TMemo;
        TabSheet2: TTabSheet;
        PageControl1: TPageControl;
        TabSheet3: TTabSheet;
        GroupBox2: TGroupBox;
        Label8: TLabel;
        Label9: TLabel;
        Label10: TLabel;
        Label11: TLabel;
        Label12: TLabel;
        ComboBox6: TComboBox;
        ComboBox7: TComboBox;
        ComboBox8: TComboBox;
        ComboBox9: TComboBox;
        ComboBox10: TComboBox;
        Button2: TButton;
        Button3: TButton;
        Memo1: TMemo;
        TabSheet4: TTabSheet;
        GroupBox3: TGroupBox;
        Label13: TLabel;
        Label14: TLabel;
        Label15: TLabel;
        Label16: TLabel;
        Label17: TLabel;
        Label18: TLabel;
        ComboBox11: TComboBox;
        ComboBox12: TComboBox;
        ComboBox13: TComboBox;
        ComboBox14: TComboBox;
        ComboBox15: TComboBox;
        Button4: TButton;
        TabSheet5: TTabSheet;
        GroupBox4: TGroupBox;
        Button5: TButton;
        Button6: TButton;
        Button7: TButton;
        Button8: TButton;
        GroupBox5: TGroupBox;
        Memo2: TMemo;
        TabSheet6: TTabSheet;
        GroupBox6: TGroupBox;
        Label19: TLabel;
        Label20: TLabel;
        Label21: TLabel;
        Label22: TLabel;
        Label23: TLabel;
        Label24: TLabel;
        Label25: TLabel;
        Label26: TLabel;
        Label27: TLabel;
        Label28: TLabel;
        Label29: TLabel;
        Label30: TLabel;
        Label31: TLabel;
        Label32: TLabel;
        Label33: TLabel;
        Label34: TLabel;
        Edit1: TEdit;
        Edit2: TEdit;
        Edit3: TEdit;
        Edit4: TEdit;
        Edit5: TEdit;
        Edit6: TEdit;
        Edit7: TEdit;
        Edit8: TEdit;
        Edit9: TEdit;
        Edit10: TEdit;
        Edit11: TEdit;
        Edit12: TEdit;
        Edit13: TEdit;
        Edit14: TEdit;
        Edit15: TEdit;
        Edit16: TEdit;
        RadioGroup1: TRadioGroup;
        Button9: TButton;
        TabSheet7: TTabSheet;
        GroupBox7: TGroupBox;
        Label35: TLabel;
        Label36: TLabel;
        Label37: TLabel;
        Label38: TLabel;
        Label48: TLabel;
        Edit17: TEdit;
        Edit18: TEdit;
        Edit19: TEdit;
        Edit20: TEdit;
        Edit29: TEdit;
        Button10: TButton;
        Button11: TButton;
        GroupBox8: TGroupBox;
        ComboBox16: TComboBox;
        TabSheet8: TTabSheet;
        GroupBox9: TGroupBox;
        Label39: TLabel;
        Label40: TLabel;
        Edit21: TEdit;
        Edit22: TEdit;
        GroupBox10: TGroupBox;
        ComboBox17: TComboBox;
        GroupBox11: TGroupBox;
        ComboBox18: TComboBox;
        Button12: TButton;
        Button13: TButton;
        Button14: TButton;
        Button15: TButton;
        TabSheet9: TTabSheet;
        GroupBox12: TGroupBox;
        Label41: TLabel;
        Label42: TLabel;
        Edit23: TEdit;
        Edit24: TEdit;
        GroupBox13: TGroupBox;
        Label43: TLabel;
        Label44: TLabel;
        Label45: TLabel;
        Label46: TLabel;
        Edit25: TEdit;
        Edit26: TEdit;
        Edit27: TEdit;
        Edit28: TEdit;
        GroupBox14: TGroupBox;
        ComboBox19: TComboBox;
        Button16: TButton;
        Button17: TButton;
        TabSheet10: TTabSheet;
        GroupBox15: TGroupBox;
        Label47: TLabel;
        Memo3: TMemo;
        TabSheet11: TTabSheet;
        TabSheet12: TTabSheet;
        Memo4: TMemo;
        GroupBox17: TGroupBox;
        Label50: TLabel;
        ImageOff: TImage;
        ImageOn: TImage;
        Label49: TLabel;
        Label51: TLabel;
        Label52: TLabel;
        Label53: TLabel;
        Button19: TButton;
        Button20: TButton;
        procedure FormShow(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure comReaderReceiveData(Sender: TObject; Buffer: Pointer;
          BufferLength: Word);
        procedure btnTestReaderClick(Sender: TObject);
        procedure btnSeekCardClick(Sender: TObject);
        procedure btnCollisionClick(Sender: TObject);
        procedure btnSelectClick(Sender: TObject);
        procedure btnTerminateClick(Sender: TObject);
        procedure btnPwdDwnClick(Sender: TObject);
        procedure btnBlockRdClick(Sender: TObject);
        procedure btnBlockWtClick(Sender: TObject);
        procedure btnBlockInitClick(Sender: TObject);
        procedure cbRWSecChange(Sender: TObject);
        procedure btnBlockReadClick(Sender: TObject);
        procedure btnBlockAddClick(Sender: TObject);
        procedure btnBlockSubClick(Sender: TObject);
        procedure btnChPwdClick(Sender: TObject);
        procedure btnChCommClick(Sender: TObject);
        procedure memLowReDblClick(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure memComSetDblClick(Sender: TObject);
        procedure memComSeReDblClick(Sender: TObject);
        procedure Button11Click(Sender: TObject);
        procedure Button10Click(Sender: TObject);
        procedure GroupBox7DblClick(Sender: TObject);
        procedure Edit17DblClick(Sender: TObject);
        procedure Edit18DblClick(Sender: TObject);
        procedure Edit19DblClick(Sender: TObject);
        procedure Edit20DblClick(Sender: TObject);
        procedure Edit29DblClick(Sender: TObject);
        procedure Memo4DblClick(Sender: TObject);
        procedure Button18Click(Sender: TObject);
        procedure cbBaudRateChange(Sender: TObject);
        procedure edtSecPwd0DblClick(Sender: TObject);
        procedure edtSecPwd1DblClick(Sender: TObject);
        procedure edtSecPwd2DblClick(Sender: TObject);
        procedure edtSecPwd3DblClick(Sender: TObject);
        procedure edtSecPwd4DblClick(Sender: TObject);
        procedure edtSecPwd5DblClick(Sender: TObject);
        procedure edtSecPwd6DblClick(Sender: TObject);
        procedure edtSecPwd7DblClick(Sender: TObject);
        procedure edtSecPwd8DblClick(Sender: TObject);
        procedure edtSecPwd9DblClick(Sender: TObject);
        procedure edtSecPwd10DblClick(Sender: TObject);
        procedure edtSecPwd11DblClick(Sender: TObject);
        procedure edtSecPwd12DblClick(Sender: TObject);
        procedure edtSecPwd13DblClick(Sender: TObject);
        procedure edtSecPwd14DblClick(Sender: TObject);
        procedure edtSecPwd15DblClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure Button19Click(Sender: TObject);
        procedure Button20Click(Sender: TObject);
     private
        { Private declarations }                 //定义私有成员
        function exchData(orderStr : string):string;
        procedure sendData();
        procedure checkOper();
        procedure ShowStatus;
        procedure EnumComPorts(Ports: TStrings);
      public
        { Public declarations }
      end;
    
    var
        multflag : integer=0;
        frmReader : TfrmReader;          //生成TForm1类对象Form1
        curOrderNo : integer=0;         //当前操作命令号
        curOperNo : integer=0;          //当前操作码类型
        orderLst : Tstrings;       //发送的命令
        recDataLst : Tstrings;    //接收的数据
        buffer : array [0..2048] of byte;
    
    implementation
    
    {$R *.dfm}
    
    //转换发送数据格式  也就是转化为二进制
    function TfrmReader.exchData(orderStr : string):string;
    var
        ii,jj : integer;
        TmpStr : string;
        reTmpStr : string;
    begin
        if (length(orderStr)=0) then
        begin
            MessageBox(handle,'传入参数不能为空!','错误',MB_ICONERROR+MB_OK);
            result:='';     //无返回
            exit;
        end;
        if (length(orderStr) mod 2) <> 0 then      //mod求摸
        begin
            MessageBox(handle,'传入参数错误!','错误',MB_ICONERROR+MB_OK);
            result:='';
            exit;
        end;
        for ii:=1 to (length(orderStr) div 2) do
        begin
            tmpStr:=copy(orderStr,ii*2-1,2);
            jj:=strToint('$' + tmpStr);             //必须要添加上'$'
            reTmpStr:=reTmpStr+chr(jj);          //chr函数转化为ACSll代码 就是二进制代码 另外一种解释16进制字符串转换成字符串
        end;
        result:=reTmpStr; //返回
    end;
    
    //发送数据过程
    procedure TfrmReader.sendData();
    var
        orderStr : string;
    begin
        if orderLst.Count > curOrderNo then        //curOrdeNo 当前操作命令号  这里不明白
        begin
            orderStr:=orderLst.Strings[curOrderNo];
            memComSeRe.Lines.Add('==>> '+orderStr);  //在《发送接收》栏窗口显示
            orderStr:=exchData(orderStr);     //转化格式
            comReader.WriteCommData(pchar(orderStr),length(orderStr));    //发送orderstr,用于发送一个字符串到写线程,发送成功返回true,发送失败返回false,
                                                                        //执行此函数将立即得到返回值,发送操作随后执行。函数有两个参数,其中
                                                                        //pdatatowrite是要发送的字符串,dwsizeofdatatowrite 是发送的长度。
            inc(curOrderNo);    //当前操作命令号自增
        end;
    end;
    
    //接收数据过程
    procedure TfrmReader.comReaderReceiveData(Sender: TObject; Buffer: Pointer;
      BufferLength: Word);
    var
        ii,i : integer;
        recStr : string;
        tmpStr,tmpStr1 : string;
    begin
        recStr:='';
        SetLength(tmpStr, BufferLength);//定义tmpstr的长度就是 BufferLength
        move(buffer^,pchar(tmpStr)^,BufferLength); //这里是一个固定的格式就跟copy一样的
        for ii:=1 to BufferLength do
        begin
            recStr:=recStr+intTohex(ord(tmpStr[ii]),2);   //字符串转换成16进制字符串
        end;                                            //以上这个是接收的固定格式
        memComSeRe.Lines.Add('<<== '+recStr); //《发送接收》栏窗口显示
        tmpStr1:= copy(recStr,3,2);   //从第三位拷贝,连续拷贝两个字符
        if   strtoint('$'+tmpStr1)= $0E then
          begin
            curOperNo:=16;   //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
            Button18.Enabled :=true;     //<采集器设置>栏选择扇区号按钮使能
            recDataLst.Clear();
            Memo4.Lines.Add('              多卡采集启动!              ');
          end;
    
        recDataLst.Add(recStr);
        if curOrderNo < orderLst.Count then
            sendData()
        else begin
            checkOper();    //检查返回的数据并显示
            memComSeRe.Lines.Append('');     //和add一样的结果
        end;
    end;
    
    //检查返回的数据并显示
    procedure tfrmReader.checkOper();
    var
        i,ii,jj : integer;
        tmpStr,tmpStr1,tmpStr2,tmpStr3 : string;
    begin
        case curOperNo of
            0 : begin
                    for i:=0 to recDataLst.Count-1 do
                        if copy(recDataLst.Strings[i],3,2)<>'00' then
                        begin
                            memComSet.Lines.Add('读卡器连结失败');
                            memComSet.Lines.Add('');
                            exit;
                        end;
                    memComSet.Lines.Add('读卡器连结成功');
                    memComSet.Lines.Add('');
                end;
            1 : begin
                    memLowRe.Lines.Add('命令: 寻卡');
                    if copy(recDataLst.Strings[0],3,2)<>'00' then //如果返回的命令字为00则说明讯卡失败
                        memLowRe.Lines.Add('结果: 寻卡失败')
                    else
                    begin
                        memLowRe.Lines.Add('结果: 寻卡成功');
                        if copy(recDataLst.Strings[0],5,2)='04' then    //这个请看RC500通信协议04表示的是Mifare one
                            memLowRe.Lines.Add('该卡片为Mifare one')
                        else
                            memLowRe.Lines.Add('该卡片为其它类型');
                    end;
                    memLowRe.Lines.Add('');   //空出来一行
                end;
            2 : begin
                    memLowRe.Lines.Add('命令: 防冲突');
                    if copy(recDataLst.Strings[0],3,2)<>'00' then      //下面的都是一样的只要命令字返回00则表示的是失败
                        memLowRe.Lines.Add('结果: 防冲突失败')
                    else begin
                        memLowRe.Lines.Add('结果: 防冲突成功');
                        tmpStr:=recDataLst.Strings[0];
                        tmpStr:=copy(tmpStr,5,length(tmpStr)-4);
                        memLowRe.Lines.Add('序号: '+tmpStr);
                    end;
                    memLowRe.Lines.Add('');
                end;
            3 : begin
                    memLowRe.Lines.Add('命令: 选择');
                    if copy(recDataLst.Strings[0],3,2)<>'00' then
                        memLowRe.Lines.Add('结果: 选择失败')
                    else
                        memLowRe.Lines.Add('结果: 选择成功');
                    memLowRe.Lines.Add('');
                end;
            4 : begin
                    memLowRe.Lines.Add('命令: 终止');
                    if copy(recDataLst.Strings[0],3,2)<>'00' then
                        memLowRe.Lines.Add('结果: 终止失败')
                    else
                        memLowRe.Lines.Add('结果: 终止成功');
                    memLowRe.Lines.Add('');
                end;
            5 : begin
                    for i:=0 to recDataLst.Count-1 do
                        if copy(recDataLst.Strings[i],3,2)<>'00' then         //密码下载
                        begin
                            MessageBox(handle,'密码下载失败','失败',MB_OK);
                            exit;
                        end;
                    MessageBox(handle,'密码下载成功','成功',MB_OK);
                end;
          6 : begin
                    for i:=0 to 3 do
                    begin
                        if copy(recDataLst.Strings[i+4],3,2)<>'00' then      //检测每个扇区的块三的密码是否存在
                        begin
                            gbRWSector.Caption:=cbRWSec.Text+'读取失败';// <数据读写模块> 选择扇区的扇区号并在这个栏的大标题框中提示出来
                            exit;
                        end;                                              {09 06 60 01 FF FF FF FF FF FF 这里面06是命令字60为PICC-AYTHENT1A
                                                                          (61为PICC-AYTHENT1B),01为扇区号,12个F为密码在这里可以设置32位 }
                    end;
                    edtBlock0.Text:=copy(recDataLst.Strings[4],5,32);   //前六位是密码位,总共可以设置32位的密码
                    edtBlock1.Text:=copy(recDataLst.Strings[5],5,32);
                    edtBlock2.Text:=copy(recDataLst.Strings[6],5,32);
                    edtBlock3.Text:=copy(recDataLst.Strings[7],5,32);
                    gbRWSector.Caption:=cbRWSec.Text+'读取成功';
                end;      
            7 : begin
                    for i:=0 to recDataLst.Count-1 do
                        if copy(recDataLst.Strings[i],3,2)<>'00' then
                        begin
                            gbRWSector.Caption:=cbRWSec.Text+'写入失败';
                            exit;
                        end;
                    gbRWSector.Caption:=cbRWSec.Text+'写入成功';
                end;
            8 : begin
                    for i:=0 to recDataLst.Count-1 do
                        if copy(recDataLst.Strings[i],3,2)<>'00' then
                        begin
                            MessageBox(handle,'块值初始化失败','失败',MB_OK);
                            exit;
                        end;
                    MessageBox(handle,'块值初始化成功','成功',MB_OK);
                end;
            9 : begin
                    for i:=0 to recDataLst.Count-1 do
                        if copy(recDataLst.Strings[i],3,2)<>'00' then
                        begin
                            MessageBox(handle,'块值读取失败','失败',MB_OK);
                            exit;
                        end;
                    tmpStr1:=copy(recDataLst.Strings[4],5,8);
                    tmpStr:='';
                    for i:=3 downto 0 do
                      begin
                        tmpStr:=tmpStr + copy(tmpStr1,(i*2+1),2);
                      end;
                    edtCurValue.Text:=tmpStr;
                    MessageBox(handle,'块值读取成功','成功',MB_OK);
                end;
            10 : begin
                    for i:=0 to recDataLst.Count-1 do
                        if copy(recDataLst.Strings[i],3,2)<>'00' then
                        begin
                            MessageBox(handle,'块值加值失败','失败',MB_OK);
                            exit;
                        end;
                    MessageBox(handle,'块值加值成功','成功',MB_OK);
                end;
            11 : begin
                    for i:=0 to recDataLst.Count-1 do
                        if copy(recDataLst.Strings[i],3,2)<>'00' then
                        begin
                            MessageBox(handle,'块值减值失败','失败',MB_OK);
                            exit;
                        end;
                    MessageBox(handle,'块值减值成功','成功',MB_OK);
                end;
            12 : begin
                    for i:=0 to recDataLst.Count-1 do
                        if copy(recDataLst.Strings[i],3,2)<>'00' then
                        begin
                            MessageBox(handle,'密码修改失败','失败',MB_OK);
                            exit;
                        end;
                    MessageBox(handle,'密码修改成功','成功',MB_OK);
                end;
            13 : begin
                     if copy(recDataLst.Strings[0],3,2)<>'00' then
                        begin
                            MessageBox(handle,'下位机波特率修改失败','失败',MB_OK);
                            exit;
                        end;
                    MessageBox(handle,'下位机波特率修改成功,请把上位机波特率设置为和下位机一样!','成功',MB_OK);
                end;
            14 : begin
                    for i:=0 to recDataLst.Count-1 do
                        if copy(recDataLst.Strings[i],3,2)<>'00' then
                        begin
                            GroupBox7.Caption:=ComBoBox16.Text+'写入失败';
                            exit;
                        end;
                    GroupBox7.Caption:=ComBoBox16.Text+'写入成功';
                end;
            15 : begin
                    for i:=0 to 3 do
                    begin
                        if copy(recDataLst.Strings[i+4],3,2)<>'00' then
                        begin
                            GroupBox7.Caption:=ComBoBox16.Text+'读取失败';
                             Edit17.Text:='';
                             Edit18.Text:='';
                             Edit19.Text:='';
                             Edit20.Text:='';
                             Edit29.Text:='';
                            exit;
                        end;
                    end;
                    tmpStr3:='';
                    tmpStr:=copy(recDataLst.Strings[4],5,32);
                    tmpStr2:='';
                    for ii:=1 to (length(tmpStr) div 2) do
                      begin
                        tmpStr1:=copy(tmpStr,ii*2-1,2);
                        tmpStr2:=tmpStr2+chr(strToint('$'+tmpStr1));
                      end;
                    tmpStr3:=tmpStr3+tmpStr2;
                    tmpStr:=copy(recDataLst.Strings[5],5,32);
                    tmpStr2:='';
                    for ii:=1 to (length(tmpStr) div 2) do
                      begin
                        tmpStr1:=copy(tmpStr,ii*2-1,2);
                        tmpStr2:=tmpStr2+chr(strToint('$'+tmpStr1));
                      end;
                    tmpStr3:=tmpStr3+tmpStr2;
                    tmpStr:=copy(recDataLst.Strings[6],5,32);
                    tmpStr2:='';
                    for ii:=1 to (length(tmpStr) div 2) do
                      begin
                        tmpStr1:=copy(tmpStr,ii*2-1,2);
                        tmpStr2:=tmpStr2+chr(strToint('$'+tmpStr1));
                      end;
                    tmpStr3:=tmpStr3+tmpStr2;
    
                    jj:=1;
                    i:= integer(tmpStr3[jj]);
                    Edit17.Text:=copy(tmpStr3,jj+1,i);
                    Memo4.Lines.Add('姓名: '+Edit17.Text);
    
                    jj:=jj+i+1;
                    i:= integer(tmpStr3[jj]);
                    Edit18.Text:=copy(tmpStr3,jj+1,i);
                    Memo4.Lines.Add('性别: '+Edit18.Text);
    
                    jj:=jj+i+1;
                    i:= integer(tmpStr3[jj]);
                    Edit19.Text:=copy(tmpStr3,jj+1,i);
                    Memo4.Lines.Add('职务: '+Edit19.Text);
    
                    jj:=jj+i+1;
                    i:= integer(tmpStr3[jj]);
                    Edit20.Text:=copy(tmpStr3,jj+1,i);
                    Memo4.Lines.Add('学号: '+Edit20.Text);
    
                    jj:=jj+i+1;
                    i:= integer(tmpStr3[jj]);
                    Edit29.Text:=copy(tmpStr3,jj+1,i);
                    Memo4.Lines.Add('学校: '+Edit29.Text+#13+#10);
                    GroupBox7.Caption:=ComBoBox16.Text+'读取成功';
    
                end;
            16 : begin
                    if  length(recDataLst.Strings[0])<=30 then
                         begin
                         recDataLst.Clear();
                         exit;
                         end;
                    tmpStr := '';
                    tmpStr2:=copy(recDataLst.Strings[0],5,32);
                    tmpStr := tmpStr + tmpStr2;
                    tmpStr2:=copy(recDataLst.Strings[0],41,32);
                    tmpStr := tmpStr + tmpStr2;
                    tmpStr2:=copy(recDataLst.Strings[0],77,32);
                    tmpStr := tmpStr + tmpStr2;
                    tmpStr3:='';
                    for ii:=1 to (length(tmpStr) div 2) do
                      begin
                        tmpStr1:=copy(tmpStr,ii*2-1,2);
                        tmpStr3:=tmpStr3+chr(strToint('$'+tmpStr1));
                      end;
    
                    jj:=1;
                    i:= integer(tmpStr3[jj]);
                    Edit17.Text:=copy(tmpStr3,jj+1,i);
                    Memo4.Lines.Add('姓名:'+Edit17.Text);
    
                    jj:=jj+i+1;
                    i:= integer(tmpStr3[jj]);
                    Edit18.Text:=copy(tmpStr3,jj+1,i);
                    Memo4.Lines.Add('性别:'+Edit18.Text);
    
                    jj:=jj+i+1;
                    i:= integer(tmpStr3[jj]);
                    Edit19.Text:=copy(tmpStr3,jj+1,i);
                    Memo4.Lines.Add('职务:'+Edit19.Text);
    
                    jj:=jj+i+1;
                    i:= integer(tmpStr3[jj]);
                    Edit20.Text:=copy(tmpStr3,jj+1,i);
                    Memo4.Lines.Add('学号:'+Edit20.Text);
    
                    jj:=jj+i+1;
                    i:= integer(tmpStr3[jj]);
                    Edit29.Text:=copy(tmpStr3,jj+1,i);
                    Memo4.Lines.Add('学校:'+Edit29.Text+#13+#10);
    
                    recDataLst.Clear();
                end;
            17 : begin
                   if (copy(recDataLst.Strings[0],3,2)<>'00') then
                        MessageBox(handle,'更改扇区失败','失败',MB_OK)
                      else
                        MessageBox(handle,'更改扇区成功','成功',MB_OK);
                   curOperNo:=16;                            
                 end;
    
        end;
    end;
    
    //系统初始化
    procedure TfrmReader.FormShow(Sender: TObject);
    begin
    
        comReader.StopComm(); //关闭串口
        orderLst:=TStringList.Create;
        recDataLst:=tStringList.Create;
    
        btnChComm.Caption := '打开串口';
        cbComName.Enabled := true;   //串口号波特率校验位  数据位 停止位下拉列表使能
        cbBaudRate.Enabled := true;
        cbParity.Enabled := true;
        cbByteSize.Enabled := true;
        cbStopBits.Enabled := true;
        ImageOn.Visible   := false; //串口打开或关闭图片显示设置
        ImageOff.Visible  := true;
    
        Button18.Enabled :=false;    //选择扇区按钮不使能(采集器设置栏)
        Label50.Caption :='多卡采集模式';// (多卡采集演示栏)
        label7.Caption :='说明:'+chr(13)+'1、如果下位机的晶振是11.0592MHz,那么波特率不支持38400'
        +'和115200;如果下位机的晶振是22.1184MHz,那么将支持左边所有的波特率设置。'+chr(13)
        +'2、下位机采集系统的波特率设置只能是左边列出来的这几种,其他的暂不支持!'
        +chr(13)+'3、"设置下位机波特率"将会把修改过的波特率写入到EEPROM,请牢记已经更改了的波特率!';     //(采集器设置栏)
        label51.Caption :='注意:'+chr(13)+'0扇区0块是只读的,在写入数据的时候要把它清空,否则,无法写入数据!';//(数据读写栏)
        label52.Caption :='注意:'+chr(13)+'1、0扇区0块是只读的,无法进行初始化、加值和减值操作!'+chr(13)
        +'2、在加值、减值操作之前要先进行初始化操作!'+chr(13) + '3、输入的数值都是十六进制!';; //(块值操作栏)
        label53.Caption :='注意:'+chr(13)+'在修改密码前要先对相应的扇区进行数据读出操作!';  //(修改密码栏)
        //+chr(13)表示回车+chr(10)表示换行
        //ShowMessage('正在设置系统');
        edtOpeValue.Text:='12345678'; //(操作值(块值操作栏))
        ShowStatus;
    end;
    //释放系统资源
    procedure TfrmReader.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
        orderLst.Free();
        recDataLst.Free();
        comReader.StopComm();
    end;
    
    //扇区号变化
    procedure TfrmReader.cbRWSecChange(Sender: TObject);   //扇区号发生变化的时候块值栏变为初始值   不用看
    begin
        gbRWSector.Caption:=cbRWSec.Text;
        edtBlock0.Text:='';
        edtBlock1.Text:='';
        edtBlock2.Text:='';
        edtBlock3.Text:='';
    end;
    
    //测试读卡器.
    procedure TfrmReader.btnTestReaderClick(Sender: TObject);
    begin
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=0;      //  00成功10失败  //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        memComSeRe.Lines.Add('测试读卡器');
        orderLst.Add('020B0F');  //蜂鸣器启动表明测试读卡器按键被按下 以下都是一样的
        sendData();
    end;
    //寻卡
    procedure TfrmReader.btnSeekCardClick(Sender: TObject);
    begin
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=1;     //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        memComSeRe.Lines.Add('寻卡');
        orderLst.Add('020226'); //02为命令字,26为 卡系列号
        orderLst.Add('020B0F');
        sendData();
    end;
    //防冲突
    procedure TfrmReader.btnCollisionClick(Sender: TObject);
    begin
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=2;   //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        memComSeRe.Lines.Add('防冲突');
        orderLst.Add('0103'); //03为命令字
        orderLst.Add('020B0F');
        sendData();
    end;
    //选择卡
    procedure TfrmReader.btnSelectClick(Sender: TObject);
    begin
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=3;  //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        memComSeRe.Lines.Add('选择');
        orderLst.Add('0104');   //04为命令字即选择卡
        orderLst.Add('020B0F');
        sendData();
    end;
    //终止卡
    procedure TfrmReader.btnTerminateClick(Sender: TObject);
    begin
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=4;    //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        memComSeRe.Lines.Add('终止');
        orderLst.Add('0101');    //都是一样的   命令字  不得不佩服这个软件的编程者有很高的思维能力,写的程序一点都不乱
        orderLst.Add('020B0F');
        sendData();
    end;
    //密码下载
    procedure TfrmReader.btnPwdDwnClick(Sender: TObject);
    var
        i,j,allpwdflag : integer;
        nameStr,pwdStr,noStr,pwdOrg : string;
    begin
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=5;    //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        allpwdflag:=0;  //至少有一个密码不为空标志位
        memComSeRe.Lines.Add('密码下载');
    
        if rgSePwdOrg.ItemIndex=0 then
            pwdOrg:='60'          //60为IC卡密码的类型一个是密码A ,61为密码B
        else
            pwdOrg:='61';
        for i:=0 to ComponentCount-1 do
        begin
            if components[i] is TEdit then    //如果components[i]是TEdit类型的话就执行下面的语句
            begin
                nameStr:=components[i].Name;
                if copy(nameStr,1,9)='edtSecPwd' then
                begin
                    noStr:=copy(nameStr,10,length(nameStr)-9);
                    pwdStr:=(components[i] as TEdit).Text;
                     if pwdStr<>'' then
                     begin
                        allpwdflag:=1;
                        noStr:=intTohex(strToint(noStr),2);
                        if length(pwdStr)<12 then
                        begin
                            MessageBox(handle,PChar(noStr+' 扇区密码位数据错误'),'错误',MB_OK);
                            exit;
                        end;
                        for j:=1 to length(pwdStr) do
                            if  not (pwdStr[j] in ['0'..'9','A'..'F','a'..'f']) then   //如果超过十六进制的字符范围就警告
                            begin
                                MessageBox(handle,PChar(noStr+' 扇区密码含有非法数据'),'错误',MB_OK);
                                exit;
                            end;
                        orderLst.Add('0906'+pwdOrg+noStr+pwdStr);
                        //ShowMessage('0906'+pwdOrg+noStr+pwdStr);
                     end;
                end;
            end;
        end;
        if (allpwdflag=1) then
           begin
              orderLst.Add('020B0F');
              sendData();
           end
        else
           begin
           MessageBox(handle,'所有的密码都为空,请输入要下载的密码!','错误',MB_OK);
           //MessageBeep(10);
           end;
    end;
    //扇区内容读取
    procedure TfrmReader.btnBlockRdClick(Sender: TObject);
    var
        i : integer;
        curSectorNo : string;
    begin
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=6;     //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        curSectorNo:=intTohex(cbRWSec.ItemIndex,2);
        memComSeRe.Lines.Add(intTostr(cbRWSec.ItemIndex)+'扇区内容读取');
        orderLst.Add('020252');
        orderLst.Add('0103');
        orderLst.Add('0104');
        orderLst.Add('040560'+curSectorNO+intTohex(cbRWSec.ItemIndex*4,2));
        for i:=0 to 3 do
            orderLst.Add('0208'+intTohex(cbRWSec.ItemIndex*4+i,2));
        orderLst.Add('020B0F');
        sendData();
    end;
    //扇区数据写入
    procedure TfrmReader.btnBlockWtClick(Sender: TObject);
    var
        i : integer;
        blockCont : string;
        curSectorNo : string;
    begin
        if (edtBlock0.Text<>'') or (edtBlock1.Text<>'') or (edtBlock2.Text<>'') then    //如果《数据读写》栏的块值0,12其中有一个不是空的
       else
            exit;
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=7;        //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        curSectorNo:=intTohex(cbRWSec.ItemIndex,2);
        //memComSeRe.Lines.Add(intTostr(cbRWSec.ItemIndex)+'扇区内容写入');
        orderLst.Add('020252');
        orderLst.Add('0103');
        orderLst.Add('0104');
        orderLst.Add('040560'+curSectorNO+intTohex(cbRWSec.ItemIndex*4,2));
    
        blockCont:=edtBlock0.Text;
        if blockCont<>'' then
        begin
            if length(blockCont)<>32 then
            begin
                MessageBox(Handle,'块0数据位数错误!','错误',MB_OK);
                exit;
            end;
            for i:=1 to 32 do
                if not (blockCont[i] in ['0'..'9','A'..'F','a'..'f']) then
                begin
                    MessageBox(Handle,'块0数据含有非法内容!','错误',MB_OK);
                    exit;
                end;
            orderLst.Add('1209'+intTohex(cbRWSec.ItemIndex*4,2)+blockCont);
        end;
    
        blockCont:=edtBlock1.Text;
        if blockCont<>'' then
        begin
            if Length(blockCont)<>32 then
            begin
                MessageBox(Handle,'块1数据位数错误!','错误',MB_OK);
                exit;
            end;
            for i:=1 to 32 do
                if not (blockCont[i] in ['0'..'9','A'..'F','a'..'f']) then
                begin
                    MessageBox(Handle,'块1数据含有非法内容!','错误',MB_OK);
                    exit;
                end;
            orderLst.Add('1209'+intTohex(cbRWSec.ItemIndex*4+1,2)+blockCont);
        end;
    
    
        blockCont:=edtBlock2.Text;
        if blockCont<>'' then
        begin
            if Length(blockCont)<>32 then
            begin
                MessageBox(Handle,'块2数据位数错误!','错误',MB_OK);
                exit;
            end;
            for i:=1 to 32 do
                if not (blockCont[i] in ['0'..'9','A'..'F','a'..'f']) then
                begin
                    MessageBox(Handle,'块2数据含有非法内容!','错误',MB_OK);
                    exit;
            end;
            orderLst.Add('1209'+intTohex(cbRWSec.ItemIndex*4+2,2)+blockCont);
        end;
    
        orderLst.Add('020B0F');
        sendData();
    end;
    //块值初始化
    procedure TfrmReader.btnBlockInitClick(Sender: TObject);
    var
        blockNo,sectorNo,i,tmpInt : integer;
        blockValue,tmpStr,iniValue : string;
    begin
        if ((cbBSecSe.ItemIndex*4+cbBse.ItemIndex)=0) then   //如果绝对块号是0
          begin
             MessageBox(handle,'0扇区0块是只读的,无法进行初始化操作!','错误',MB_OK);
             exit;
          end;
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=8;     //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        sectorNo:=cbBSecSe.ItemIndex;  //cbBSecSe扇区号
        blockNo:=cbBSe.ItemIndex;      //cbBSe块号
        memComSeRe.Lines.Add(intTostr(cbRWSec.ItemIndex)+'块值初始化');
    
        blockValue:=edtOpeValue.Text;  //操作值
        if blockValue='' then
        begin
            MessageBox(handle,'操作值不能为空!','错误',MB_OK);
            exit;
        end;
        if length(blockValue)<>8 then
        begin
            MessageBox(handle,'操作值位数错误!','错误',MB_OK);
            exit;
        end;
        for i:=1 to 8 do
            if not (blockValue[i] in ['0'..'9','A'..'F','a'..'f']) then
            begin
                MessageBox(Handle,'操作数据含有非法内容!','错误',MB_OK);
                exit;
            end;
    
        orderLst.Add('020252');
        orderLst.Add('0103');
        orderLst.Add('0104');
        orderLst.Add('040560'+intTohex(sectorNo,2)+intTohex(sectorNo*4,2));
    
        //ShowMessage(intTostr(sectorNo));
        tmpStr:='';
        for i:=3 downto 0 do
        begin
          tmpStr:=tmpStr + copy(blockValue,(i*2+1),2);
        end;
        blockValue:=tmpStr;
        //ShowMessage(blockValue);
        iniValue:='';
        //ABCD(4字节)+ABCD的反码(4字节)+ABCD(4字节)
        //+add(1字节)+add的反码(1字节)+add(1字节)+add的反码(1字节) 注:其中add是绝对扇区号
        for i:=0 to 3 do
        begin
            tmpStr:=copy(blockValue,(i*2+1),2);
            tmpInt:=255-strToint('$'+tmpStr);
            //ShowMessage(tmpStr);
            iniValue:=iniValue+intTohex(tmpInt,2);
        end;
        iniValue:=blockValue+iniValue+blockValue;
    
        tmpInt:=255-(sectorNo*4+blockNo);
        tmpStr:=intTohex(sectorNo*4+blockNo,2)+intTohex(tmpInt,2);
        iniValue:=iniValue+tmpStr+tmpStr;
         //ShowMessage(iniValue);
        orderLst.Add('1209'+intTohex(sectorNo*4+blockNo,2)+iniValue);
        orderLst.Add('020B0F');
        sendData();
    end;
    //块值读取
    procedure TfrmReader.btnBlockReadClick(Sender: TObject);
    begin
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=9;     //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        memComSeRe.Lines.Add(intTostr(cbBse.ItemIndex+cbBSecSe.ItemIndex)+'块值读取');
        orderLst.Add('020252');
        orderLst.Add('0103');
        orderLst.Add('0104');
        orderLst.Add('040560'+intTohex(cbBSecSe.ItemIndex,2)+intTohex(cbBSecSe.ItemIndex*4,2));
        orderLst.Add('0208'+intTohex(cbBSecSe.ItemIndex*4+cbBse.ItemIndex,2));
        orderLst.Add('020B0F');
        sendData();
    end;
    //块值加值
    procedure TfrmReader.btnBlockAddClick(Sender: TObject);
    var
        sectorNo,blockNo,i: integer;
        blockValue,tmpStr : string;
    begin
        sectorNo:=cbBSecSe.ItemIndex*4+cbBse.ItemIndex;  //绝对块号
        if (sectorNo=0) then
          begin
             MessageBox(handle,'0扇区0块是只读的,无法进行加值操作!','错误',MB_OK);
             exit;
          end;  
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=10;   //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        memComSeRe.Lines.Add(intTostr(cbBse.ItemIndex+cbBSecSe.ItemIndex)+'块值加值');
    
        blockValue:=edtOpeValue.Text;
        if blockValue='' then
        begin
            MessageBox(handle,'操作值不能为空!','错误',MB_OK);
            exit;
        end;
        if length(blockValue)<>8 then
        begin
            MessageBox(handle,'操作值位数错误!','错误',MB_OK);
            exit;
        end;
        for i:=1 to 8 do
            if not (blockValue[i] in ['0'..'9','A'..'F','a'..'f']) then
            begin
                MessageBox(Handle,'操作数据含有非法内容!','错误',MB_OK);
                exit;
            end;
         tmpStr:='';
        for i:=3 downto 0 do
        begin
          tmpStr:=tmpStr + copy(blockValue,(i*2+1),2);
        end;
        blockValue:=tmpStr;
        orderLst.Add('020252');
        orderLst.Add('0103');
        orderLst.Add('0104');
        orderLst.Add('040560'+intTohex(cbBSecSe.ItemIndex,2)+intTohex(cbBSecSe.ItemIndex*4,2));
        orderLst.Add('080AC1'+intTohex(cbBSecSe.ItemIndex*4+cbBse.ItemIndex,2)+blockValue+intTohex(cbBSecSe.ItemIndex*4+cbBse.ItemIndex,2));
        orderLst.Add('020B0F');
        sendData();
    end;
    //块值减值
    procedure TfrmReader.btnBlockSubClick(Sender: TObject);
    var
        sectorNo,blockNo,i: integer;
        blockValue,tmpStr : string;
    begin
        sectorNo:=cbBSecSe.ItemIndex*4+cbBse.ItemIndex;  //绝对块号
        if (sectorNo=0) then
          begin
             MessageBox(handle,'0扇区0块是只读的,无法进行减值操作!','错误',MB_OK);
             exit;
          end;
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=11;     //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        memComSeRe.Lines.Add(intTostr(cbBse.ItemIndex+cbBSecSe.ItemIndex)+'块值减值');
    
        blockValue:=edtOpeValue.Text;
        if blockValue='' then
        begin
            MessageBox(handle,'操作值不能为空!','错误',MB_OK);
            exit;
        end;
        if length(blockValue)<>8 then
        begin
            MessageBox(handle,'操作值位数错误!','错误',MB_OK);
            exit;
        end;
        for i:=1 to 8 do
            if not (blockValue[i] in ['0'..'9','A'..'F','a'..'f']) then
            begin
                MessageBox(Handle,'操作数据含有非法内容!','错误',MB_OK);
                exit;
            end;
        tmpStr:='';
        for i:=3 downto 0 do
        begin
          tmpStr:=tmpStr + copy(blockValue,(i*2+1),2);
        end;
        blockValue:=tmpStr;
    
        orderLst.Add('020252');
        orderLst.Add('0103');
        orderLst.Add('0104');
        orderLst.Add('040560'+intTohex(cbBSecSe.ItemIndex,2)+intTohex(cbBSecSe.ItemIndex*4,2));
        orderLst.Add('080AC0'+intTohex(cbBSecSe.ItemIndex*4+cbBse.ItemIndex,2)+blockValue+intTohex(cbBSecSe.ItemIndex*4+cbBse.ItemIndex,2));
        orderLst.Add('020B0F');
        sendData();
    end;
    //扇区密码写入
    procedure TfrmReader.btnChPwdClick(Sender: TObject);
    var
        i : integer;
        pwdA,pwdB : string;
        curSectorNo,tmpStr : string;
    begin
        if (edtPwdA.Text<>'') or (edtPwdB.Text<>'') then
        else
            exit;
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=12;   //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        curSectorNo:=intTohex(cbChPwdSec.ItemIndex,2);
        memComSeRe.Lines.Add(intTostr(cbChPwdSec.ItemIndex)+'扇区密码写入');
        orderLst.Add('020252');
        orderLst.Add('0103');
        orderLst.Add('0104');
        orderLst.Add('040560'+curSectorNo+intTohex(cbRWSec.ItemIndex*4,2));
    
        pwdA:=edtPwdA.Text;
        if pwdA<>'' then
        begin
            if Length(pwdA)<>12 then
            begin
                MessageBox(Handle,'密码A位数错误!','错误',MB_OK);
                exit;
            end;
            for i:=1 to 12 do
                if not (pwdA[i] in ['0'..'9','A'..'F','a'..'f']) then
                begin
                    MessageBox(Handle,'密码A含有非法内容!','错误',MB_OK);
                    exit;
                end;
        end;
    
        pwdB:=edtPwdB.Text;
        if pwdB<>'' then
        begin
            if Length(pwdB)<>12 then
            begin
                MessageBox(Handle,'密码B位数错误!','错误',MB_OK);
                exit;
            end;
            for i:=1 to 12 do
                if not (pwdB[i] in ['0'..'9','A'..'F','a'..'f']) then
                begin
                    MessageBox(Handle,'密码B含有非法内容!','错误',MB_OK);
                    exit;
                end;
        end;
        if pwdB='' then
            for i:=1 to 12 do
            begin
                tmpStr:=copy(pwdA,i,1);
                tmpStr:=intTostr(15-strToint('$'+tmpStr));
                pwdB:=pwdB+tmpStr;
            end;
    
        orderLst.Add('1209'+intTohex(cbChPwdSec.ItemIndex*4+3,2)+pwdA+'ff078069'+pwdB);
    
        orderLst.Add('020B0F');
        sendData();
    
    end;
    //设置下位机的波特率。
    procedure TfrmReader.Button1Click(Sender: TObject);
     var
       tempstr : string;
    begin
        case ComboBox2.ItemIndex of
            0 : tempstr:='00';
            1 : tempstr:='01';
            2 : tempstr:='02';
            3 : tempstr:='03';
            4 : tempstr:='04';
            5 : tempstr:='05';
            6 : tempstr:='06';
            else tempstr:='00';
        end;
        if  ((tempstr='04') or (tempstr='06')) then
          begin
          MessageBox(Handle,'下位机暂不支持该波特率!','非法波特率',MB_OK);   {提示信息}
          exit;
          end;
        orderLst.Clear();     //定义的私有成员
        recDataLst.Clear();   //定义的私有成员
        curOrderNo:=0;         //当前操作命令号
        curOperNo:=13;          //当前操作码类型//这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        memComSeRe.Lines.Add('设置下位机的波特率');
        orderLst.Add('020D'+tempstr);
          //ShowMessage('020D'+tempstr);
        sendData();
    end;
    
    procedure TfrmReader.btnChCommClick(Sender: TObject);       //(上机参数设置)
    var
         tmpStr : array[1..3] of string;
    begin
          if btnChComm.Caption = '打开串口' then
             begin
               tmpStr[1]:=cbComName.Text;  //把端口名赋给数组 1
               comReader.CommName:=tmpStr[1]; //吧数组1的内容送给COM插件的相关属性
               tmpStr[2]:=cbBaudRate.Text;    //波特率赋给数组2
               comReader.BaudRate:=strToint(tmpStr[2]); //吧数组2的内容送给COM插件的相关属性
               comReader.Parity:=tParity(cbParity.ItemIndex); // 奇偶校验位
               //memComSet.Lines.Add('检验位: '+cbParity.Text);
               { Even-表示偶校验     None-表示无校验     Odd-表示奇校验
               Mark-表示校验位为1  Space-表示校验位为0   }
               comReader.ByteSize:=TByteSize(cbByteSize.ItemIndex);  //数据位
               comReader.StopBits:=TStopBits(cbStopBits.ItemIndex);  //停止位
               comReader.StartComm;  //打开串口
    
               btnChComm.Caption := '关闭串口';
               cbComName.Enabled := false;  {这些都变成不使能}
               cbBaudRate.Enabled := false;
               cbParity.Enabled := false;
               cbByteSize.Enabled := false;
               cbStopBits.Enabled := false;
               ImageOff.Visible  := false;
               ImageOn.Visible   := true;     //“关闭”图片显示
    
               MessageBeep(10);     //调用系统声音
               memComSet.Lines.Add('串口为: '+tmpStr[1]);     //一下的都是(上位机参数设置栏)的 显示模块
               memComSet.Lines.Add('波特率: '+tmpStr[2]);
               memComSet.Lines.Add('检验位: '+cbParity.Text);
               memComSet.Lines.Add('数据位: '+cbByteSize.Text);
               memComSet.Lines.Add('停止位: '+cbStopBits.Text);
               memComSet.Lines.Add('串口参数设置成功');
               memComSet.Lines.Add('');
             end
          else //if Button1.Caption = '关闭串口' then
             begin
              comReader.StopComm;// 关闭串口
              btnChComm.Caption := '打开串口';
              cbComName.Enabled := true;
              cbBaudRate.Enabled := true;
              cbParity.Enabled := true;
              cbByteSize.Enabled := true;
              cbStopBits.Enabled := true;
              ImageOn.Visible   := false;
              ImageOff.Visible  := true;
            end;
      ShowStatus; //把当前的状态显示到(上位机参数设置栏)上的lebal中
    end;
    //清空低级操作TMemo内容
    procedure TfrmReader.memLowReDblClick(Sender: TObject);
    begin
        memLowRe.Text:='';        //(低级操作栏)双击清空内容
    end;
    //清空波特率设置TMemo内容
    procedure TfrmReader.memComSetDblClick(Sender: TObject);
    begin
        memComSet.Text:='';       //(上位机参数设置栏)双击清空内容
    end;
    //清空发送和接收TMemo内容
    procedure TfrmReader.memComSeReDblClick(Sender: TObject);
    begin
        memComSeRe.Text:='';     //(发送接收栏)双击清空内容
    end;
    //图书信息写入电子标签
    procedure TfrmReader.Button11Click(Sender: TObject);
    var
        i ,totalcount: integer;
        blockCont ,tempstr: string;
        curSectorNo : string;
    begin
         if (Edit17.Text<>'') then
            else
              begin
               MessageBox(Handle,'图书编号不能为空!','错误',MB_OK);
               exit;
               end;
            orderLst.Clear();
            recDataLst.Clear();
            curOrderNo:=0;
            curOperNo:=14;   //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
            curSectorNo:=intTohex(ComBoBox16.ItemIndex,2);
            //memComSeRe.Lines.Add(intTostr(ComBoBox16.ItemIndex)+'扇区内容写入');
            orderLst.Add('020252');
            orderLst.Add('0103');
            orderLst.Add('0104');
            orderLst.Add('040560'+curSectorNO+intTohex(ComBoBox16.ItemIndex*4,2));
         //Edit17.Text:='1234';
        //Edit18.Text:='789-5';
        //Edit19.Text:='C语言教程';
        //Edit20.Text:='谭浩强';
        //Edit29.Text:='高等教育出版社';
    
        tempstr:='';
        //totalcount:=6+length(Edit17.Text)+length(Edit18.Text)+length(Edit19.Text)+length(Edit20.Text)+length(Edit29.Text);
        //tempstr:=inttohex(totalcount,2);
    
        //ShowMessage(inttostr(totalcount));
       
        tempstr:=tempstr + inttohex(length(Edit17.Text),2);
    
        //ShowMessage(inttostr(length(tempstr)));
            for i:=1 to length(Edit17.Text) do
             tempstr :=tempstr + inttohex(integer(edit17.Text[i]),2);
    
        tempstr:=tempstr + inttohex(length(Edit18.Text),2);
            for i:=1 to length(Edit18.Text) do
             tempstr :=tempstr + inttohex(integer(edit18.Text[i]),2);
    
         tempstr:=tempstr + inttohex(length(Edit19.Text),2);
            for i:=1 to length(Edit19.Text) do
             tempstr :=tempstr + inttohex(integer(edit19.Text[i]),2);
    
         tempstr:=tempstr + inttohex(length(Edit20.Text),2);
            for i:=1 to length(Edit20.Text) do
             tempstr :=tempstr + inttohex(integer(edit20.Text[i]),2);
    
         tempstr:=tempstr + inttohex(length(Edit29.Text),2);
            for i:=1 to length(Edit29.Text) do
             tempstr :=tempstr + inttohex(integer(edit29.Text[i]),2);
    
           for i:= length(tempstr)+1 to 96 do
                tempstr := tempstr + '0';
    
           //ShowMessage(tempstr);
           //Memo4.Text :=tempstr;
            for i:=0 to 2 do
               begin
                 blockCont:=copy(tempstr,i*32+1,32);
                 orderLst.Add('1209'+intTohex(ComBoBox16.ItemIndex*4+i,2)+blockCont);
                end;
               orderLst.Add('020B0F');
               sendData();
    end;
    
    procedure TfrmReader.Button10Click(Sender: TObject);
    var
        i : integer;
        curSectorNo : string;
    begin
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=15;    //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        curSectorNo:=intTohex(ComBoBox16.ItemIndex,2);
        memComSeRe.Lines.Add(intTostr(ComBoBox16.ItemIndex)+'扇区内容读取');
        orderLst.Add('020252');
        orderLst.Add('0103');
        orderLst.Add('0104');
        orderLst.Add('040560'+curSectorNO+intTohex(ComBoBox16.ItemIndex*4,2));
        for i:=0 to 2 do
            orderLst.Add('0208'+intTohex(ComBoBox16.ItemIndex*4+i,2));
        orderLst.Add('020B0F');
        sendData();
    end;
    
    procedure TfrmReader.GroupBox7DblClick(Sender: TObject);
    begin
        Edit17.Text:='';
        Edit18.Text:='';
        Edit19.Text:='';
        Edit20.Text:='';
        Edit29.Text:='';
    end;
    
    procedure TfrmReader.Edit17DblClick(Sender: TObject);
    begin
        Edit17.Text:='';
    end;
    
    procedure TfrmReader.Edit18DblClick(Sender: TObject);
    begin
        Edit18.Text:='';
    end;
    
    procedure TfrmReader.Edit19DblClick(Sender: TObject);
    begin
       Edit19.Text:='';
    end;
    
    procedure TfrmReader.Edit20DblClick(Sender: TObject);
    begin
         Edit20.Text:='';
    end;
    
    procedure TfrmReader.Edit29DblClick(Sender: TObject);
    begin
         Edit29.Text:='';
    end;
    
    procedure TfrmReader.Memo4DblClick(Sender: TObject);
    begin
         Memo4.Text:='';
    end;
    
    procedure TfrmReader.Button18Click(Sender: TObject);
    begin
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=17;    //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        //memComSeRe.Lines.Add('设置下位机的存储图书信息的扇区号');
        orderLst.Add('020F'+intTohex(ComboBox20.ItemIndex,2));  
        //orderLst.Add('020B0F');
        sendData();
    end; 
    //
    
    procedure TfrmReader.ShowStatus;
    begin
      if btnChComm.Caption = '关闭串口' then   {如果检测到打开串口按钮被打开则}
      begin
        edStatus.Text := Format('当前串口状态: %s已打开  波特率%s   校验位%s   数据位%s   停止位%s  ', [cbComName.Text,
          {cbComName.Text,}IntToStr(comReader.BaudRate), cbParity.Text,
          cbByteSize.Text, cbStopBits.Text]);   {Format()函数用来将字符串按指定的格式输出%[<参数位置>:][-][<所占宽度>][.<小数位数>]<类型>
                                                  说明:若缺省[<参数位置>:],则从左到右依次分配各参数;"-"表示左对齐,若缺省则
                                                  右对齐;<类型>为参数的类型     其中这里的 %后的S表示的是将结果转化为字符串型数据}
      end
      else
        edStatus.Text := ' 当前串口状态: '+cbComName.Text+'已关闭';
    end;
    
     
    
    procedure TfrmReader.cbBaudRateChange(Sender: TObject);  //波特率改变之后发生的状况
    var
      BaudRate: Integer;
    begin
      if cbBaudRate.Text = 'Custom' then
      begin
        cbBaudRate.Style := csDropDown; //csDropDown是由编辑框和列表框组合而成的组合框,列表框中的任一项都是高度相同的字符串
        cbBaudRate.SetFocus;    // 设置键盘焦点  (也就是键盘输入有效))
        btnChComm.Enabled := false; //“打开串口”按钮不使能
      end
      else
      begin
        if cbBaudRate.ItemIndex > 0 then
          cbBaudRate.Style := csDropDownList; // csDropDownList只有列表框而没有编辑框,任一项是高度一致的字符串
          //下面是自定义波特率的
        if TryStrToInt(cbBaudRate.Text, BaudRate) then   //TryStrToInt:返回字符串S转换成整数Value是否成功
        begin
          comReader.BaudRate := BaudRate;   //吧选择的串口信息传递到COMreader的信息当中
          btnChComm.Enabled := true;         //“打开串口”按钮使能
        end
        else
          btnChComm.Enabled := false;
      end;
    end;
    
    procedure TfrmReader.edtSecPwd0DblClick(Sender: TObject);
    begin
         edtSecPwd0.Text :='';                                   //双击使它变为空
    end;
    
    procedure TfrmReader.edtSecPwd1DblClick(Sender: TObject);
    begin
         edtSecPwd1.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd2DblClick(Sender: TObject);
    begin
            edtSecPwd2.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd3DblClick(Sender: TObject);
    begin
          edtSecPwd3.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd4DblClick(Sender: TObject);
    begin
       edtSecPwd4.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd5DblClick(Sender: TObject);
    begin
         edtSecPwd5.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd6DblClick(Sender: TObject);
    begin
         edtSecPwd6.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd7DblClick(Sender: TObject);
    begin
        edtSecPwd7.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd8DblClick(Sender: TObject);
    begin
        edtSecPwd8.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd9DblClick(Sender: TObject);
    begin
       edtSecPwd9.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd10DblClick(Sender: TObject);
    begin
        edtSecPwd10.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd11DblClick(Sender: TObject);
    begin
        edtSecPwd11.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd12DblClick(Sender: TObject);
    begin
         edtSecPwd12.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd13DblClick(Sender: TObject);
    begin
       edtSecPwd13.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd14DblClick(Sender: TObject);
    begin
         edtSecPwd14.Text :='';
    end;
    
    procedure TfrmReader.edtSecPwd15DblClick(Sender: TObject);
    begin
         edtSecPwd15.Text :='';
    end;
    
    procedure TfrmReader.FormCreate(Sender: TObject);
    begin
    
      EnumComPorts(cbComName.Items);    //得到串口列表
      EnumComPorts(ComboBox1.Items);    //得到串口列表
      if (copy(cbComName.Items[1],1,2)<>'') then    //如果有得到空闲的串口的信息那么就显示获取的串口的第一位
          begin
            cbComName.ItemIndex := 1;
            ComboBox1.ItemIndex := 1;
          end
        else
           begin
             cbComName.ItemIndex:=0;
             ComboBox1.ItemIndex:=0;
             end;
      comReader.CommName := cbComName.Text;  //把得到的串口的值付给COMM控件的相关属性
      cbBaudRate.ItemIndex := 4;  //波特率下拉框的默认值为第四位
      comReader.BaudRate := StrToInt(cbBaudRate.Text);    //COMM控件的波特率设置
      cbParity.ItemIndex := 0;
      comReader.Parity := None;   {以下的都为默认值不用管}
      cbByteSize.ItemIndex := 3;
      comReader.ByteSize := _8;
      cbStopBits.ItemIndex := 0;
      comReader.StopBits := _1;
    end;
    
    //得到串口列表
    procedure TfrmReader.EnumComPorts(Ports: TStrings);//枚举串口列表(不用管它是怎样实现的。。底层的)
    var
      KeyHandle: HKEY;
      ErrCode, Index: Integer;
      ValueName, Data: string;
      ValueLen, DataLen, ValueType: DWORD;
      TmpPorts: TStringList;
    begin
      ErrCode := RegOpenKeyEx(
        HKEY_LOCAL_MACHINE,
        'HARDWARE\DEVICEMAP\SERIALCOMM',
        0,
        KEY_READ,
        KeyHandle);
    
      if ErrCode <> ERROR_SUCCESS then
        Exit;  // raise EComPort.Create(CError_RegError, ErrCode);
    
      TmpPorts := TStringList.Create;
      try
        Index := 0;
        repeat
          ValueLen := 256;
          DataLen := 256;
          SetLength(ValueName, ValueLen);
          SetLength(Data, DataLen);
          ErrCode := RegEnumValue(
            KeyHandle,
            Index,
            PChar(ValueName),
            Cardinal(ValueLen),
            nil,
            @ValueType,
            PByte(PChar(Data)),
            @DataLen);
    
          if ErrCode = ERROR_SUCCESS then
          begin
            SetLength(Data, DataLen);
            TmpPorts.Add(Data);
            Inc(Index);
          end
          else
            if ErrCode <> ERROR_NO_MORE_ITEMS then
              exit; //raise EComPort.Create(CError_RegError, ErrCode);
    
        until (ErrCode <> ERROR_SUCCESS) ;
    
        TmpPorts.Sort;
        Ports.Assign(TmpPorts);
      finally
        RegCloseKey(KeyHandle);
        TmpPorts.Free;
      end;
    
    end;        //到这里都是串口枚举函数
    
    procedure TfrmReader.Button19Click(Sender: TObject);
    begin
        edtSecPwd0.Text :='';
        edtSecPwd1.Text :='';
        edtSecPwd2.Text :='';
        edtSecPwd3.Text :='';
        edtSecPwd4.Text :='';
        edtSecPwd5.Text :='';
        edtSecPwd6.Text :='';
        edtSecPwd7.Text :='';
        edtSecPwd8.Text :='';
        edtSecPwd9.Text :='';
        edtSecPwd10.Text :='';
        edtSecPwd11.Text :='';
        edtSecPwd12.Text :='';
        edtSecPwd13.Text :='';
        edtSecPwd14.Text :='';
        edtSecPwd15.Text :='';
    end;
    
    procedure TfrmReader.Button20Click(Sender: TObject);
    begin
        edtSecPwd0.Text :='FFFFFFFFFFFF';
        edtSecPwd1.Text :='FFFFFFFFFFFF';
        edtSecPwd2.Text :='FFFFFFFFFFFF';
        edtSecPwd3.Text :='FFFFFFFFFFFF';
        edtSecPwd4.Text :='FFFFFFFFFFFF';
        edtSecPwd5.Text :='FFFFFFFFFFFF';
        edtSecPwd6.Text :='FFFFFFFFFFFF';
        edtSecPwd7.Text :='FFFFFFFFFFFF';
        edtSecPwd8.Text :='FFFFFFFFFFFF';
        edtSecPwd9.Text :='FFFFFFFFFFFF';
        edtSecPwd10.Text :='FFFFFFFFFFFF';
        edtSecPwd11.Text :='FFFFFFFFFFFF';
        edtSecPwd12.Text :='FFFFFFFFFFFF';
        edtSecPwd13.Text :='FFFFFFFFFFFF';
        edtSecPwd14.Text :='FFFFFFFFFFFF';
        edtSecPwd15.Text :='FFFFFFFFFFFF';
    end;
    end.
  • 相关阅读:
    吃货联盟点单系统
    新闻发布系统进程汇报
    jsp九大内置对象响应类型
    jsp get与post请求乱码问题
    jsp第一章 动态网页开发基础
    C# MD5加密
    调用存储过程
    JSONObject跟JSONArray来自不同的包会有不同的功能
    upm配置文件
    iuap
  • 原文地址:https://www.cnblogs.com/622698abc/p/2612672.html
Copyright © 2011-2022 走看看