5,392
社区成员
发帖
与我相关
我的任务
分享
unit CRT_310_NR01Handler;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ShareMem, StdCtrls, TLoggerUnit;
const
//$30:弹出卡到前端;$31:回收卡;$36:弹出卡到后端;$38:弹出卡到前端不持卡位
InCardState : array[0..3] of Byte = ($30,$31,$36,$38);
//密码为
A_KEY: array[0..5] of Byte = ($00,$00,$00,$00,$00,$00);
//金额所在块
MONEY_BLOCK = $10;
MONEY_BLOCK_1 = $11;
Sector_Number = $04;
//金额检验位
MONEY_KEY: array[0..9] of Char = ('F','E','D','C','B','A','9','8','7','6');
type
TTrackInfo =packed record
ReadStute : String; //读卡状态
TrackData : String; //数据
end;
TPACKET=array[0..1024] of Byte;
//主类
TNR01Handler = class
private
{ Private declarations }
SHandles :THandle;
rec :integer;
FPortOpen :Boolean;
public
{ Public declarations }
//16位块数据
CardBlock :Array[0..15] of Byte;
//磁卡卡号数据
BankCard :string;
//磁卡二轨数据
MagCardSid :String;
//磁卡三轨数据
MagCardTid :string;
//IC卡号
ICCardNumber :string;
//卡内余额值
ICCardBalance :String;
//是否需要重新初始化读卡器硬件
YNInitICCard :Boolean;
//类初始化
Constructor Create(Aowner:TComponent);
destructor Destroy; override;
//打开串口
function OpenSerialPort(CardComPort :String;CardBaudRate :Integer): Boolean; stdcall;
//关闭串口
procedure CloseSerialPort(); stdcall;
//初始化读卡器
function InitICCardHandler(): Boolean; stdcall;
//串口是否已打开
function IsPortOpen(): Boolean;
//解析错误信息
procedure ICRWErrMsg(StError1:Byte;StError0:Byte); stdcall;
//操作硬件日志 ,出错时才写
procedure WriteOpLog(Memo: String); stdcall;
//设置前端禁止进卡方式
function NoCardIn() :Boolean; stdcall;
//查询电动读卡器内卡片状态
function CardStatus() :SmallInt; stdcall;
//设置前端开关进卡方式
function InCardBySwitch() :Boolean; stdcall;
end;
function CRT310NROpenWithBaut(Port:String;Const BautRate:Integer):THANDLE; stdcall; external 'CRT_310_NR01.dll';
Function CRT310NRClose(ComHandle:THANDLE):Integer; stdcall;external 'CRT_310_NR01.dll';
function CancelCommand(ComHandle: Integer): Integer; stdcall;external 'CRT_310_NR01.dll';
function RS232_ExeCommand(ComHandle: Integer; CmCode:Byte; CpCode:Byte;CmDatalen:Integer;CmData:TPACKET;var ReType:Byte;var St0:Byte;var St1:Byte;var ReDataLen:Integer;var ReData:TPACKET): Integer; stdcall;external 'CRT_310_NR01.dll';
var
NR01Handler :TNR01Handler;
implementation
constructor TNR01Handler.Create(Aowner:TComponent);
begin
SHandles := INVALID_HANDLE_VALUE;
rec :=0;
FPortOpen :=False;
YNInitICCard :=True;
inherited Create;
end;
destructor TNR01Handler.Destroy;
begin
if SHandles<>INVALID_HANDLE_VALUE then
begin
CloseHandle(SHandles);
FreeLibrary(SHandles);
end;
end;
//打开串口
function TNR01Handler.OpenSerialPort(CardComPort :String;CardBaudRate :Integer): Boolean; stdcall;
begin
Result := False;
FPortOpen :=False;
SHandles := INVALID_HANDLE_VALUE;
try
SHandles := CRT310NROpenWithBaut(CardComPort,CardBaudRate);
if SHandles<>INVALID_HANDLE_VALUE then
begin
FPortOpen := True;
Result :=True;
end else
Result := False;
except
WriteOpLog(CardComPort+'*'+IntToStr(CardBaudRate)+'*电动读卡器端口打开失败');
Result := false;
end;
end;
//关闭电动读卡器串口端口
procedure TNR01Handler.CloseSerialPort(); stdcall;
begin
if SHandles<>INVALID_HANDLE_VALUE then
begin
rec := CRT310NRClose(SHandles);
end;
end;
//初始化电动读卡器设备
function TNR01Handler.InitICCardHandler(): Boolean; stdcall;
var
CmData,ReData:TPACKET;
CmDataLen,ReDataLen,i :integer;
CmCode,PmCode,ReType,St1,St0 :Byte;
begin
Result :=False;
if SHandles = 0 then begin
Result :=False;
exit;
end;
for i := 0 to 1024 do begin
CmData[i]:=0 ;
ReData[i]:=0 ;
end;
CmCode:=$30;
PmCode:=$31;
CmDataLen:=13;
CmData[0]:= $33;
CmData[1]:= $32;
CmData[2]:= $34;
rec:=RS232_ExeCommand(SHandles,CmCode,PmCode,CmDataLen,CmData,ReType,St0,St1,ReDataLen,ReData);
if rec <> 0 then begin
Result :=False;
exit;
end;
if Retype=$50 then begin
Result :=True;
YNInitICCard :=False;
end
else if Retype=$4e then begin
Result :=False;
ICRWErrMsg(St0,St1);
end
else begin
WriteOpLog('Communication Error');
end ;
end;
function TNR01Handler.IsPortOpen(): Boolean;
begin
Result := FPortOpen;
end;
//记录详细的错误日志
procedure TNR01Handler.ICRWErrMsg(StError1:Byte;StError0:Byte); stdcall;
begin
WriteOpLog(' Error Code:'+chr(StError1)+chr(StError0));
YNInitICCard := True;
end;
//写硬件日志
procedure TNR01Handler.WriteOpLog(Memo: String); stdcall;
begin
TLogger.GetInstance.Debug('读卡器错误信息:'+Memo);
end;
//设置前端禁止进卡方式
function TNR01Handler.NoCardIn() :Boolean; stdcall;
var
CmData,ReData:TPACKET;
CmDataLen,ReDataLen,i :integer;
CmCode,PmCode,ReType,St1,St0 :Byte;
begin
Result :=False;
if SHandles = 0 then begin
Result :=False;
exit;
end;
for i := 0 to 1024 do begin
CmData[i]:=0 ;
ReData[i]:=0 ;
end;
CmCode:=$3A;
PmCode:=$31;
CmDataLen:=0;
rec:=RS232_ExeCommand(SHandles,CmCode,PmCode,CmDataLen,CmData,ReType,St0,St1,ReDataLen,ReData);
if rec <> 0 then begin
Result :=False;
exit;
end;
if Retype=$50 then begin
Result :=True;
end
else if Retype=$4e then begin
Result :=False;
ICRWErrMsg(St0,St1);
end
else begin
WriteOpLog('NoCardIn :Communication Error');
end ;
end;
//查询电动读卡器内卡片状态
function TNR01Handler.CardStatus() :SmallInt; stdcall;
var
CmData,ReData:TPACKET;
CmDataLen,ReDataLen,i :integer;
CmCode,PmCode,ReType,St1,St0 :Byte;
begin
Result :=0;
if SHandles = 0 then begin
Result :=0;
exit;
end;
for i := 0 to 1024 do begin
CmData[i]:=0 ;
ReData[i]:=0 ;
end;
CmCode:=$31;
PmCode:=$30;
CmDataLen:=0;
rec:=RS232_ExeCommand(SHandles,CmCode,PmCode,CmDataLen,CmData,ReType,St0,St1,ReDataLen,ReData);
if rec <> 0 then begin
Result :=0;
exit;
end;
if Retype=$50 then begin
case St1 of
$30 : Result :=1;//卡机内无卡(包括出卡口)
$31 : Result :=2;//出卡口处有一张卡
$32 : Result :=3;//卡机内有卡
end;
end
else if Retype=$4e then begin
Result :=0;
ICRWErrMsg(St0,St1);
end
else begin
WriteOpLog('CardStatus :Communication Error');
end ;
end;
//设置前端“开关”进卡方式
function TNR01Handler.InCardBySwitch() :Boolean; stdcall;
var
CmData,ReData:TPACKET;
CmDataLen,ReDataLen,i :integer;
CmCode,PmCode,ReType,St1,St0 :Byte;
begin
Result :=False;
if SHandles = 0 then begin
Result :=False;
exit;
end;
for i := 0 to 1024 do begin
CmData[i]:=0 ;
ReData[i]:=0 ;
end;
CmCode:=$3A;
PmCode:=$30;
CmDataLen:=1;
CmData[0]:=$30;
rec:=RS232_ExeCommand(SHandles,CmCode,PmCode,CmDataLen,CmData,ReType,St0,St1,ReDataLen,ReData);
if rec <> 0 then begin
Result :=False;
exit;
end;
if Retype=$50 then begin
Result :=True;
end
else if Retype=$4e then begin
Result :=False;
ICRWErrMsg(St0,St1);
end
else begin
WriteOpLog('InCardBySwitch :Communication Error');
end ;
end;
end.
unit ICCardTest;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, CRT_310_NR01Handler;
type
TForm1 = class(TForm)
CommRateCombo: TComboBox;
CommPortCombo: TComboBox;
Label2: TLabel;
Label1: TLabel;
OpenCommPortBtn: TButton;
CloseCommPortBtn: TButton;
CardStatusBtn: TButton;
ReaderResetBtn: TButton;
btn1: TButton;
procedure OpenCommPortBtnClick(Sender: TObject);
procedure CloseCommPortBtnClick(Sender: TObject);
procedure ReaderResetBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
NR01Handler :TNR01Handler;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
NR01Handler := NR01Handler.Create(self);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if NR01Handler<>nil then
begin
NR01Handler.Free;
end;
end;
procedure TForm1.OpenCommPortBtnClick(Sender: TObject);
begin
NR01Handler.OpenSerialPort('COM2',38400);
if NR01Handler.IsPortOpen() then
ShowMessage('串口初始化成功!')
else
ShowMessage('串口打开失败!');
end;
procedure TForm1.CloseCommPortBtnClick(Sender: TObject);
begin
NR01Handler.CloseSerialPort();
end;
procedure TForm1.ReaderResetBtnClick(Sender: TObject);
begin
if NR01Handler.InitICCardHandler() then
ShowMessage('初始化成功')
else
ShowMessage('初始化失败');
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
Close;
end;
end.