关于使用读卡器的(50分)

G

geyufly

Unregistered / Unconfirmed
GUEST, unregistred user!
我做了一个机房管理系统,是学生使用磁卡划卡上机那种,其他都完了,就剩下和划卡器那块的连接,
以前没有接触过划卡器,我是想磁卡上设置好卡号,学生进入机房时划了后读出卡号,可是
不知道该查些什么资料,我想主要是把我的程序和读卡器连接起来就行了。给点建议吗。
 
查资料有意义吗?
买个读卡器,有的是带sample的
调用一下它的sample使用的函数
很容易搞定的

不过留意,有的sample可能和你使用的语言不同
上次我碰上的是用C++ Builder 的sample.
那就用C++ BUILDER改喽
 
读卡器本身带有函数说明的,我曾经做过
 
看读卡器带的说明书或附的盘,上面肯定有连接函数
 
很容易的,把刷卡器接上,看看说明,试两边就ok了
 
它的接口函数有是用DELPHI写的吗,哪位大哥能发个给我看看吗?
我是学生要买一个的话需要花我200多块钱啊!!!帮帮忙了。
 
easy,不过要看你使用的谁家的读卡器,然后会有附带的程序例子才可以阿。
 
去賣读卡器的公司要資料啊!
他們會提供接口的資料!
 
各位能推荐一下吗,我真的没钱买读卡器,帮我讲讲吗?
 
提个醒:不要看读、写卡器的价格
要看卡的价格。这是一个误区。
 
我刚做了一个磁卡的程序,需要和厂家联系要他的DLL函数

下面是厂家给我的邮件




常州三晶电子有限公司



SJE900系列密码键盘 ----- win95/win98/winNT/win2000 下32位动态链接库(KeyCard.DLL)函数说明

1) INT ReadKey(CHAR *SET,CHAR *RDATA,INT CMD)
功能:控制sje900进行读密码键盘操作,按ESC键可退出.

返回: 整型
= 1: 读密码键盘正确,
-1: 所选串行口打不开
-3: 串口设置错误
-5: 用户 ESC 关闭密码键盘

参数:
SET: 字符串,用来设置串口.
格式:"1,9600,N,8,1" ------ (1=com1或2=com2),
(9600=baud9600或4800=baud4800
或2400=baud2400或1200=baud1200),
(N=无校验或O=奇校验或N=偶校验),
(8=8个数据位或7=7个数据位),
(1=1个停止位或2=2个停止位).
如:"2,9600,O,7,1" 表示串口2,波特率9600.奇校验,7个数据位,1个停止位.


cmd:表示密码键盘的命令代号.

如:1 请输入密码。
2 请再输入一次。
3 密码键盘初始化。


RDATA: 读密码键盘数据输出缓冲区(用于存放读密码键盘成功后的返回数据)
字符串,长度不少于300字节.

如:
ReadKey("1,9600,N,8,1",RDATA,1)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式,同时键盘放语音提示“请输入密码”并
从密码键盘读取数据(存放在RDATA中)



ReadKey("1,9600,N,8,1",RDATA,2)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式,同时键盘放语音提示“请再输入一次”并
从密码键盘读取数据(存放在RDATA中)


//===============================================================================================



SJE300系列磁卡读写机 ----- win95/win98/win2000 下32位动态链接库(DLL)函数说明

1) INT Wcard(CHAR *SET,CHAR *WDATA,INT TRACK)

功能:控制SJE353B磁卡读写机进行写磁卡操作,按ESC键可退出.

返回: 整型
= 1: 写卡正确
-1: 所选串行口打不开
-2: 与磁卡读写机通信失败(磁卡机没有与主机连接或连接不正确)
-3: 串口设置错误
-4: 写卡错误
-5: 用户 ESC 退出当前操作


参数:
SET: 字符串,用来设置串口.
格式:"1,9600,N,8,1" ------ (1=com1或2=com2),
(9600=baud9600或4800=baud4800
或2400=baud2400或1200=baud1200),
(N=无校验或O=奇校验或N=偶校验),
(8=8个数据位或7=7个数据位),
(1=1个停止位或2=2个停止位).
如:"2,9600,O,7,1" 表示串口2,波特率9600.奇校验,7个数据位,1个停止位.

TRACK: 需要进行写卡操作的磁道选择号(具体定义如下:)
-------- 1:选择第1磁轨
2:选择第2磁轨
3:选择第3磁轨
4:选择第2和第1磁轨
5:选择第2和第3磁轨

当TRACK 为6时,此时的功能为硬复位。

WDATA: 字符串,所要向卡上写的数据.
格式:"磁道1数据" ------ 写第1轨数据(此时 TRACK 为1)
"磁道2数据" ------ 写第2轨数据(此时 TRACK 为2)
"磁道3数据" ------ 写第3轨数据(此时 TRACK 为3)
"磁道2数据a磁道1数据" ------ 写第2轨数据和第1轨数据(此时 TRACK 为4,
小写字符a作为磁道2和磁道1的数据的间隔符)
"磁道2数据a磁道3数据" ------ 写第2轨数据和第3轨数据(此时 TRACK 为5,
小写字符a作为磁道2和磁道3的数据的间隔符)

其中: 小写字符a为磁道2与磁道1(或磁道2与磁道3)的数据的分隔符
1轨数据可为字母或数字,最多76个
2轨数据只可为数字,最多37个
3轨数据只可为数字,最多104个

如: Wcard("1,9600,N,8,1","1111111111",1)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式向第1磁轨中写入数据:1111111111

Wcard("1,9600,N,8,1","2222222222",2)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式向第2磁轨中写入数据:2222222222

Wcard("1,9600,N,8,1","3333333333",3)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式向第3磁轨中写入数据:3333333333

Wcard("1,9600,N,8,1","2222222222a1111111111",4)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式向第2磁轨中写入数据:2222222222 并且
向第1磁轨中写入数据:1111111111

Wcard("1,9600,N,8,1","2222222222a3333333333",5)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式向第2磁轨中写入数据:2222222222 并且
向第3磁轨中写入数据:3333333333

具体见SJE300系列磁卡读写机使用说明书





2) INT Rcard(CHAR *SET,CHAR *RDATA,INT TRACK)

功能:控制sje353b进行读磁卡操作,按ESC键可退出.

返回: 整型
= 1: 读卡正确,
-1: 所选串行口打不开
-2: 与磁卡读写机通信失败(磁卡机没有与主机连接或连接不正确)
-3: 串口设置错误
-4: 读卡错误
-5: 用户 ESC 退出当前操作

参数:
SET: 字符串,用来设置串口.
格式:"1,9600,N,8,1" ------ (1=com1或2=com2),
(9600=baud9600或4800=baud4800
或2400=baud2400或1200=baud1200),
(N=无校验或O=奇校验或N=偶校验),
(8=8个数据位或7=7个数据位),
(1=1个停止位或2=2个停止位).
如:"2,9600,O,7,1" 表示串口2,波特率9600.奇校验,7个数据位,1个停止位.

TRACK: 需要进行写卡操作的磁道选择号(具体定义如下:)
-------- 1:选择第1磁轨
2:选择第2磁轨
3:选择第3磁轨
4:选择第2和第1磁轨
5:选择第2和第3磁轨

RDATA: 读卡数据输出缓冲区(用于存放读卡成功后的返回数据)
字符串,长度不少于300字节.

读卡成功返回格式:
RDATA = "磁道1数据" ------- 返回磁道1数据(此时 TRACK 为1)
RDATA = "磁道2数据" ------- 返回磁道2数据(此时 TRACK 为2)
RDATA = "磁道3数据" ------- 返回磁道3数据(此时 TRACK 为3)
RDATA = "磁道2数据a磁道1数据" ------- 返回磁道2数据和磁道1数据(此时 TRACK 为4)
RDATA = "磁道2数据a磁道3数据" ------- 返回磁道2数据和磁道3数据(此时 TRACK 为5)

读卡错误: Rcard函数返回值为-4

其中: 小写字符a为磁道2与磁道1(或磁道2与磁道3)的数据的分隔符
1道数据可为字母或数字,最多76个
2道数据只可为数字,最多37个
3数据只可为数字,最多104个

如:
Rcard("1,9600,N,8,1",RDATA,1)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式从第1磁轨中读取数据(存放在RDATA中)

Rcard("1,9600,N,8,1",RDATA,2)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式从第2磁轨中读取数据(存放在RDATA中)

Rcard("1,9600,N,8,1",RDATA,3)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式从第3磁轨中读取数据(存放在RDATA中)

Rcard("1,9600,N,8,1",RDATA,4)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式从第2磁轨和第1磁轨中读取数据
(存放在RDATA中,中间以小写字符a作间隔)

Rcard("1,9600,N,8,1",RDATA,5)
-------- 表示通过串行口1以波特率9600BPS,8位数据位,1位停止位,
无校验的方式从第2磁轨和第3磁轨中读取数据
(存放在RDATA中,中间以小写字符a作间隔)

具体见SJE300系列磁卡读写机使用说明书



调用例程:

函数调用声明:
extern "C" int PASCAL EXPORT Rcard(char *set,char *rdata,int track);
extern "C" int PASCAL EXPORT Wcard(char *set,char *wdata,int track);

写卡例程:

......

// 根据所选择的磁轨号(和磁轨数据)判断写操作条件是否满足
if (m_Check1 == TRUE && m_Check2 == TRUE)
{
if (strlen(tk2)==0 && strlen(tk3)==0)
{ MessageBox("请输入2,3磁轨数据!"); return; }
else
{
if (strlen(tk2) == 0 )
{ MessageBox("请输入2轨数据!"); return; }
if (strlen(tk3) == 0 )
{ MessageBox("请输入3轨数据!"); return; }
}

}
else
{
if ( m_Check1 == TRUE && strlen(tk2) == 0 )
{ MessageBox("请输入2轨数据!"); return; }
if ( m_Check2 == TRUE && strlen(tk3) == 0 )
{ MessageBox("请输入3轨数据!"); return; }

}

// 从编辑框中取得数据,准备写卡
if ( m_Check1 == TRUE && m_Check2 == TRUE)
{
strcpy(wdata,tk2);
// 小写字符'a'为磁轨2与磁轨3(或磁轨2与磁轨1)的数据之间的分隔符
strcat(wdata,"a");
strcat(wdata,tk3);
track = 5; //'5'选择第2磁轨和第3磁轨
}
else
{
if ( m_Check1 == TRUE)
{ strcpy(wdata,tk2); track = 2; } //'2'选择第2磁轨
if ( m_Check2 == TRUE)
{ strcpy(wdata,tk3); track = 3; } //'3'选择第3磁轨
}

// 选择串行口端口号
m_Combo1.GetWindowText(set,5);
if (strcmp(set,"COM1") == 0 )
strcpy(set,"1");
else if (strcmp(set,"COM2") == 0 )
strcpy(set,"2");
else if (strcmp(set,"COM3") == 0 )
strcpy(set,"3");
else if (strcmp(set,"COM4") == 0 )
strcpy(set,"4");

// 波特率为默认为9600BPS,无校验方式,8位数据位,1位停止位
strcat(set,",9600,n,8,1");

// 调用动态链接库CARD_DLL.DLL中的函数Wcard进行写卡操作
retv = Wcard(set,wdata,track);


根据retv的值做相应的处理。


读卡同理。


 
这是我写的读卡程序

//==============================================================================
//4.4.读卡**********************************************************************
//==============================================================================
procedure TForm_Client.Data_ReadCard(Sender: TObject);
var CardHandle: THandle;
ReadCard: function(vSET: PChar; RDATA: PChar; TRACK: integer): integer; stdcall;
TempStr: PChar;
begin
//============================================================================
//调用DLL例程*****************************************************************
//============================================================================
GetMem(TempStr,512);{为指针分配内存}
CardHandle := LoadLibrary('card_dll');
if CardHandle<=0
then raise Exception.Create('动态链接库card_dll加载失败,错误代码:'+IntToStr(GetLastError))
else @ReadCard := GetProcAddress(CardHandle, 'Rcard');
if not Assigned(ReadCard)
then raise Exception.Create('动态链接库card_dll函数Rcard加载失败,错误代码:'+IntToStr(GetLastError)) else
begin
case ReadCard('1,9600,N,8,1',TempStr,2) of
1: if (Panel_Main.Controls[TabControl.TabIndex] is TexDockForm) then
try
(Panel_Main.Controls[TabControl.TabIndex] as TexDockForm).Data_TreeSel(0, Trim(StrPas(TempStr)));
except
end;
-1: MessageBox(Self.Handle, Pchar('所选串行口打不开!'), '提示!', MB_OK+MB_ICONINFORMATION);
-2: MessageBox(Self.Handle, Pchar('与磁卡读写机通信失败(磁卡机没有与主机连接或连接不正确)'), '提示!', MB_OK+MB_ICONINFORMATION);
-3: MessageBox(Self.Handle, Pchar('串口设置错误!'), '提示!', MB_OK+MB_ICONINFORMATION);
-4: MessageBox(Self.Handle, Pchar('读卡错误!'), '提示!', MB_OK+MB_ICONINFORMATION);
-5: MessageBox(Self.Handle, Pchar('用户退出当前操作!'), '提示!', MB_OK+MB_ICONINFORMATION);
end;
end;
FreeMem(TempStr);
FreeLibrary(CardHandle);
end;
 
这是写卡程序

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
procedure TForm_Cell.Data_WriteCard(Sender: TObject);
var CardHandle: THandle;
WriteCard: function(vSET: PChar; WDATA: PChar; TRACK: integer): integer; stdcall;
begin
if ClientDataSet_Cell.FieldByName('制卡次数').AsInteger>0 then
if MessageBox(Self.Handle,PChar('制卡次数为'+ClientDataSet_Cell.FieldByName('制卡次数').AsString+'次,是否继续?'),'提示!',MB_YESNO+MB_ICONQUESTION)=IDNO then Abort;
//============================================================================
//调用DLL例程*****************************************************************
//============================================================================
CardHandle := LoadLibrary('card_dll');
if CardHandle<=0
then raise Exception.Create('动态链接库card_dll加载失败,错误代码:'+IntToStr(GetLastError))
else @WriteCard := GetProcAddress(CardHandle, 'Wcard');
if not Assigned(WriteCard)
then raise Exception.Create('动态链接库card_dll函数Wcard加载失败,错误代码:'+IntToStr(GetLastError)) else
begin
case WriteCard(PChar('1,9600,N,8,1'),PChar(ClientDataSet_Cell.FieldByName('用户编号').AsString),2) of
1: begin
ClientDataSet_Cell.Edit;
ClientDataSet_Cell.FieldByName('制卡日期').AsDateTime := Remote.Date;
ClientDataSet_Cell.FieldByName('制卡次数').AsInteger := ClientDataSet_Cell.FieldByName('制卡次数').AsInteger + 1;
try Data_SafeSave(ClientDataSet_Cell); except end;
MessageBox(Self.Handle, Pchar('用户编号写入成功!'), '提示!', MB_OK+MB_ICONINFORMATION);
end;
-1: MessageBox(Self.Handle, Pchar('所选串行口打不开!'), '提示!', MB_OK+MB_ICONINFORMATION);
-2: MessageBox(Self.Handle, Pchar('与磁卡读写机通信失败(磁卡机没有与主机连接或连接不正确)'), '提示!', MB_OK+MB_ICONINFORMATION);
-3: MessageBox(Self.Handle, Pchar('串口设置错误!'), '提示!', MB_OK+MB_ICONINFORMATION);
-4: MessageBox(Self.Handle, Pchar('写卡错误!'), '提示!', MB_OK+MB_ICONINFORMATION);
-5: MessageBox(Self.Handle, Pchar('用户退出当前操作!'), '提示!', MB_OK+MB_ICONINFORMATION);
end;
end;
FreeLibrary(CardHandle);
end;
 
没有读卡器,你怎么写读卡程序?
 
接受答案了.
 
顶部