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,1,2其中有一个不是空的 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.