初学串口编程,用厂商提供的例子能读写RF感应卡,但我想用SpComm来开发驱动程序,
可是SpComm该如何读写RF感应卡?卡里面的数据我该怎么读(我是用厂家的程序往卡里写的数据).看了一些例子,只能发送(没有报错),但就是接收不到数据.那位高手搞过串口编程,能指点一下吗?
可是SpComm该如何读写RF感应卡?卡里面的数据我该怎么读(我是用厂家的程序往卡里写的数据).看了一些例子,只能发送(没有报错),但就是接收不到数据.那位高手搞过串口编程,能指点一下吗?
打开串口:
procedure TForm1.butOpenClick(Sender: TObject);
var
portno: integer;
begin
Commhandle:=opencomm('com1:9600,n,8,1');
if Commhandle>0 then
begin
lstexesta.caption:='Open com'+inttohex(portno+1,1)+ ' OK';
butwr.Enabled:=true;
butrd.enabled:=true;
butbeep.Enabled:=true;
end
else
lstexesta.caption:='Open COMx error';
end;写卡:
procedure TForm1.butWrClick(Sender: TObject);
var mykey:keystruc;
retval:longint;
stmp:string;
begin
mykey.cardtype :=strtoint(trim(edit0.text));
stmp:=trim(edit1.Text);
hextobin(pchar(stmp),pchar(@mykey.hotelid),3);
mykey.AreaID :=strtoint(trim(edit2.text));
mykey.FloorID:=strtoint(trim(edit3.text));
mykey.roomid:=strtoint(trim(edit4.text));
mykey.CardID:=strtoint(trim(edit5.Text));
mykey.OffOn:=0;
stmp:=trim(edit7.Text);
hextobin(pchar(stmp),pchar(@mykey.sdate),5);
stmp:=trim(edit8.text);
hextobin(pchar(stmp),pchar(@mykey.edate),5);
stmp:=trim(edit9.Text);
hextobin(pchar(stmp),pchar(@mykey.STime),2);
stmp:=trim(edit10.Text);
hextobin(pchar(stmp),pchar(@mykey.eTime),2);
mykey.FloorCot:=strtoint(trim(edit11.text));
retval:=WRkey_t5557(commhandle,mykey);
if retval<>0 then
begin
lstexesta.caption:=' Wr Card error ';
dv_beep(commhandle,10);
dv_beep(commhandle,10);
end
else
begin
dv_beep(commhandle,10);
lstexesta.caption:=' Wr Card OK';
end;
end;读卡:
procedure TForm1.butRDClick(Sender: TObject);
var
mykey:KeyStruc;
retval:longint;
ptmp:array[0..64] of char;
begin
retval:=rdkey_t5557(commhandle,mykey);
if (retval=0) then
begin
lstexesta.caption:='Rd card ok';
dv_beep(commhandle,10);
end
else
begin
lstexesta.caption:=format(' rd card error %.2x%',[retval]);
dv_beep(commhandle,10);
dv_beep(commhandle,10);
exit
end;
edit0.Text:=inttostr(mykey.cardtype);
fillchar(ptmp,63,0);
bintohex(pchar(@mykey.hotelid),ptmp,3);
edit1.Text:=ptmp;
edit2.text:=inttostr(mykey.AreaID);
edit3.text:=inttostr(mykey.FloorID);
edit4.Text:=inttostr(mykey.roomid);
edit5.Text:=inttostr(mykey.cardID);
edit6.Text:='0';
fillchar(ptmp,63,0);
bintohex(pchar(@mykey.sdate),ptmp,6);
edit7.Text:=ptmp;
bintohex(pchar(@mykey.edate),ptmp,6);
edit8.Text:=ptmp;
fillchar(ptmp,63,0);
bintohex(pchar(@mykey.stime),ptmp,2);
edit9.Text:=ptmp;
bintohex(pchar(@mykey.etime),ptmp,2);
edit10.Text:=ptmp;
edit11.Text:=inttostr(mykey.FloorCot);
end;引用的单元
unit hotel1;
interfaceType KeyStruc=RECORD
cardtype:byte;
HotelID: array[0..2] of byte;//
AreaID: byte;
FloorID:byte;
roomid:Byte;
CardID:Byte;
OffOn:Byte;
SDate:array[0..4] of byte;
EDate:array[0..4] of byte;
STime:array[0..1] of Byte;
ETime:array[0..1] of byte;
FloorCot:byte;
End;Const
conGuest =1;
conWaiter=2;
conClear =3;
conMange =4;
conWarn =5;function rdkey_4150(Commhandle:longint;var keyinfo:KeyStruc):longint;stdcall;
external 'hotel1.dll';
function wrkey_4150(Commhandle:longint;var keyinfo:KeyStruc):longint;stdcall;
external 'hotel1.dll';
function rdkey_ib91(Commhandle:longint;var keyinfo:KeyStruc):longint;stdcall;
external 'hotel1.dll';
function wrkey_ib91(Commhandle:longint;var keyinfo:KeyStruc):longint;stdcall;
external 'hotel1.dll';
function rdkey_t5557(Commhandle:longint;var keyinfo:KeyStruc):longint;stdcall;
external 'hotel1.dll';
function wrkey_t5557(Commhandle:longint;var keyinfo:KeyStruc):longint;stdcall;
external 'hotel1.dll';Function rdkey_4442(commhandle:longint;var keys:keystruc):longint;stdcall;
external 'hotel1.dll';
Function wrkey_4442(commhandle:longint;var keys:keystruc):longint;stdcall;
external 'hotel1.dll';implementationend.
如果用API来写驱动,需要哪些资料?
用api,你只需要操作串口的打开,关闭,收,发 就足够了.open,write,read几个函数就可以了.
如果你要做真正的驱动,就是把读卡器做成一个windows设备,象word可以调用打印机那样,那据我所知delphi恐怕是不够的,你需要使用winddk或者DriverWizard之类的开发工具
有一个简单的办法分析封装的协议,
就是你用串口调试助手,再找个两个母头的线,连接计算机上的两个Com口。
然后分别执行各个函数,这样你就能得到计算机发送出去的命令了。然后在用串口调试助手发送刚才收到的命令(按照接收时候的格式发送,此时就不用两个母头的线了,直接用线连接读卡器),
就可以得到读卡器返回来的数据了。这样便于你分析发送和接收的协议,如果能分析出来,也就不用受dll文件的受制了。
注意,协议有可能加密了,否则应该不会给你提供dll文件。
谢谢大家的支持.
写卡:
procedure TForm1.butWrClick(Sender: TObject);
var mykey:keystruc;
retval:longint;
stmp:string;
begin
mykey.cardtype :=strtoint(trim(edit0.text));
stmp:=trim(edit1.Text);
hextobin(pchar(stmp),pchar(@mykey.hotelid),3);
mykey.AreaID :=strtoint(trim(edit2.text));
mykey.FloorID:=strtoint(trim(edit3.text));
mykey.roomid:=strtoint(trim(edit4.text));
mykey.CardID:=strtoint(trim(edit5.Text));
mykey.OffOn:=0;
stmp:=trim(edit7.Text);
hextobin(pchar(stmp),pchar(@mykey.sdate),5);
stmp:=trim(edit8.text);
hextobin(pchar(stmp),pchar(@mykey.edate),5);
stmp:=trim(edit9.Text);
hextobin(pchar(stmp),pchar(@mykey.STime),2);
stmp:=trim(edit10.Text);
hextobin(pchar(stmp),pchar(@mykey.eTime),2);
mykey.FloorCot:=strtoint(trim(edit11.text));
retval:=WRkey_t5557(commhandle,mykey);
if retval <>0 then
begin
lstexesta.caption:=' Wr Card error ';
dv_beep(commhandle,10);
dv_beep(commhandle,10);
end
else
begin
dv_beep(commhandle,10);
lstexesta.caption:=' Wr Card OK';
end;
end;
引用到你的程序中,把用的dll和所引用的單元一并引用到你所開發的單元中,按著卡的數據結構寫數據,應該是可以的。我以前也是這么干的,就是數據結構那邊要搞清楚它的類型和長度。
波特率: 9600
数据位: 8
停止位: 1
校验位: None(无)2、通信协议
2.1 协议格式:
STX ADDR LEN CMD/STU DATA BCC
STX:通讯起始符,1字节,其值为 0x02。
ADDR:设备地址号,1字节,0对所有地址有效。
LEN:数据长度,1字节,CMD/STU+DATA的字节数。
CMD/STU:命令字节(Host->Reader)或状态字节(Reader->Host),1字节。
DATA:数据字段,字节个数不定,该段有可能不存在。
BCC:为区段核对字符,1字节,为数据包除STX,BCC以外所有字节的异或值。2.2 命令集:
功能 发送命令 返回状态 数据及说明蜂鸣器控制 0x22 0x00 蜂鸣控制字(1字节)蜂鸣控制字→ =0: 响一声,=2: 响二声
T5557卡读序列号 0x41 0x00 卡序列号(8字节)
T5557卡读卡数据 0x42 0x00 卡数据(24字节)
T5557卡写卡数据 0x43 0x00 卡数据(24字节)
返回状态代码
代码 代表意义
0x00 正常执行
其它值 错误 → 无卡以上就是我现在有的资料,那位给一个简单的示例.
var
buf:array of byte;
i:integer;
bcc:byte;
begin
setlength(buf,1+1+1+1+1+1);buf[0]:=$02; //STX
buf[1]:=$00; //ADDR
buf[2]:=1; //LEN
buf[3]:=$22; //CMD/STU 蜂鸣器
buf[4]:=0; //DATA 响一声
bcc:=0;
for i:=1 to length(buf)-1 do
bcc:=bcc xor buf[i];buf[5]:=bcc; //BCCcomm1.WriteCommData(pchar(@buf[0]),length(buf));
end;当然,这之前比要保证comm1的各个状态已经设置好,并且已用stratcom打开
comm1的onReceiveData事件处理接收数据,如果收到$00,表示执行成功
改成for i:=1 to length(buf)-1-1 do
你上边的例子,我是试了.可是接收数据该怎么写.如果我想发送"谢谢您"这个字符串,怎么改代码.因为我发现不能发字符串.