📄 controlclass.~pas
字号:
end;
function TCardReader.CardNo_SoftToHard(ACardNoSoft: string): TCardNoHard;
var
mCard: integer;
mResult : TCardNoHard;
mStr : string;
begin
if Length(ACardNoSoft) <> 8 then
begin
raise Exception.Create('卡号的位数不正确!');
end;
try
//=============卡号的编码方式==================
//mCard := StrToInt(ACardNoSoft);
//mStr := Copy(ACardNoSoft,1,2);
mResult.N1 := Copy(ACardNoSoft,1,2);
mResult.N2 := Copy(ACardNoSoft,3,2);
mResult.N3 := Copy(ACardNoSoft,5,2);
mResult.N4 := Copy(ACardNoSoft,7,2);
except
mResult.N1 := '00';
mResult.N2 := '00';
mResult.N3 := '00';
mResult.N4 := '00';
end;
Result := mResult;
end;
constructor TCardReader.Create(Address: string; APortNo: integer);
begin
//SetAddress(Address);
FPortNo := APortNo;
FMSComm := TMSComm.Create(nil);
OpenPort();
//========================
//TCommand.Create();
TBottomMsg.Create();
end;
constructor TCardReader.Create(APortNo: integer);
begin
FPortNo := APortNo;
FMSComm := TMSComm.Create(nil);
OpenPort();
FCommand := TBottomMsg.Create();
end;
destructor TCardReader.Destroy;
begin
if FMSComm.PortOpen then FMSComm.PortOpen:= False;
FMSComm.Free;
//========================
FCommand.Free;
FBottomMsg.Free;
inherited;
end;
procedure TCardReader.OpenPort;
begin
FMSComm.InputMode := 1; //comInputModeBinary;
FMSComm.CommPort := FPortNo;
FMSComm.Settings := '9600,n,8,1';
//open the port
if not FMSComm.PortOpen then FMSComm.PortOpen:= True;
end;
function TCardReader.ReadCard(var ACardUse: TCardUse): integer;
var
mCounter : integer;
mCommand : TCommand;
mBottomMsg : TBottomMsg;
mBuf: array of byte;
Year,Month,Day,Hour,Min,Sec: word;
begin
mCommand := TCommand.Create('B3B3B3 02 FD 14 XX');
mBottomMsg := TBottomMsg.Create();
//通信次数计数器
mCounter := 0 ;
while mCounter < TRY_TIMES do
begin
//输出上位机报文
FMSComm.Output := mCommand.FBuffer;
//等待读卡机响应
Sleep(WAIT_TIME);
//检查上传报文长度
if FMSComm.InBufferCount >= 10 then
begin
//将OLE变量付值给树组
SetLength(mBuf,FMSComm.InBufferCount);
//读取上传报文
mBuf := FMSComm.Input;
//设置下位机应答信息类分析
mBottomMsg.SetBuffer(mBuf);
//分析应答数据
if mBottomMsg.GetPosStr(4) = '07' then break;
end;
Inc(mCounter);
end;
//放弃通信
if mCounter >= TRY_TIMES then
begin
Result := -1 ;
end
//场内没有卡
else if mBottomMsg.GetPosStr(7) = '12' then
begin
Result := -2;
end
else begin
ACardUse.Card := mBottomMsg.GetPosStr(8)
+mBottomMsg.GetPosStr(9)
+mBottomMsg.GetPosStr(10)
+mBottomMsg.GetPosStr(11);
end;
mCommand.Free;
mBottomMsg.Free;
end;
function TCardReader.ReadComplexCard(var ACardUse: TComplexCardUse): integer;
var
mCounter : integer;
mCommand : TCommand;
mBottomMsg : TBottomMsg;
mBuf: array of byte;
Year1,Year2,Month,Day,Hour,Min,Sec: word;
begin
mCommand := TCommand.Create('B3B3B3 03 FC 0A 04 XX');
mBottomMsg := TBottomMsg.Create();
//mCommand.ParamByPos(1,FAddr1);//地址
//mCommand.ParamByPos(2,FAddr2);//地址
mCounter := 0 ;
while mCounter < TRY_TIMES do
begin
FMSComm.Output := mCommand.FBuffer;
Sleep(WAIT_TIME);
if FMSComm.InBufferCount >= 8 then
begin
//将OLE变量付值给树组
SetLength(mBuf,FMSComm.InBufferCount);
mBuf := FMSComm.Input;
mBottomMsg.SetBuffer(mBuf);
//分析应答数据
if mBottomMsg.GetPosStr(7) = '00' then break;
end;
Inc(mCounter);
end;
//放弃通信
if mCounter >= TRY_TIMES then
begin
Result := -1 ;
Exit;
end
else begin
ACardUse.MainClass := mBottomMsg.GetPosStr(8+1);
ACardUse.SlaveClass := mBottomMsg.GetPosStr(8+2);
end;
mCommand.Free;
mBottomMsg.Free;
//==================第五区
mCommand := TCommand.Create('B3B3B3 03 FC 0A 05 XX');
mBottomMsg := TBottomMsg.Create();
mCounter := 0 ;
while mCounter < TRY_TIMES do
begin
FMSComm.Output := mCommand.FBuffer;
Sleep(WAIT_TIME);
if FMSComm.InBufferCount >= 8 then
begin
//将OLE变量付值给树组
SetLength(mBuf,FMSComm.InBufferCount);
mBuf := FMSComm.Input;
mBottomMsg.SetBuffer(mBuf);
//分析应答数据
if mBottomMsg.GetPosStr(7) = '00' then break;
end;
Inc(mCounter);
end;
//放弃通信
if mCounter >= TRY_TIMES then
begin
Result := -1 ;
Exit;
end
else begin
ACardUse.EnterAddr1 := mBottomMsg.GetPosStr(8+1);
ACardUse.EnterAddr2 := mBottomMsg.GetPosStr(8+2);
ACardUse.LeaveAddr1 := mBottomMsg.GetPosStr(8+3);
ACardUse.LeaveAddr2 := mBottomMsg.GetPosStr(8+4);
end;
mCommand.Free;
mBottomMsg.Free;
//===============第六区
mCommand := TCommand.Create('B3B3B3 03 FC 0A 06 XX');
mBottomMsg := TBottomMsg.Create();
mCounter := 0 ;
while mCounter < TRY_TIMES do
begin
FMSComm.Output := mCommand.FBuffer;
Sleep(WAIT_TIME);
if FMSComm.InBufferCount >= 8 then
begin
//将OLE变量付值给树组
SetLength(mBuf,FMSComm.InBufferCount);
mBuf := FMSComm.Input;
mBottomMsg.SetBuffer(mBuf);
//分析应答数据
if mBottomMsg.GetPosStr(7) = '00' then break;
end;
Inc(mCounter);
end;
//放弃通信
if mCounter >= TRY_TIMES then
begin
Result := -1 ;
Exit;
end
else begin
ACardUse.Card := mBottomMsg.GetPosStr(8+1)
+mBottomMsg.GetPosStr(8+2)
+mBottomMsg.GetPosStr(8+3)
+mBottomMsg.GetPosStr(8+4);
end;
mCommand.Free;
mBottomMsg.Free;
//===============第七区
mCommand := TCommand.Create('B3B3B3 03 FC 0A 07 XX');
mBottomMsg := TBottomMsg.Create();
mCounter := 0 ;
while mCounter < TRY_TIMES do
begin
FMSComm.Output := mCommand.FBuffer;
Sleep(WAIT_TIME);
if FMSComm.InBufferCount >= 17 then
begin
//将OLE变量付值给树组
SetLength(mBuf,FMSComm.InBufferCount);
mBuf := FMSComm.Input;
mBottomMsg.SetBuffer(mBuf);
//分析应答数据
if mBottomMsg.GetPosStr(7) = '00' then break;
end;
Inc(mCounter);
end;
//放弃通信
if mCounter >= TRY_TIMES then
begin
Result := -1 ;
Exit;
end
else begin
try
//解析时间
Year1 := StrToInt(mBottomMsg.GetPosStr(9));
Year2 := StrToInt(mBottomMsg.GetPosStr(10));
Month := StrToInt(mBottomMsg.GetPosStr(11));
Day := StrToInt(mBottomMsg.GetPosStr(12));
Hour := StrToInt(mBottomMsg.GetPosStr(13));
Min := StrToInt(mBottomMsg.GetPosStr(14));
Sec := StrToInt(mBottomMsg.GetPosStr(15));
ACardUse.EnterTime := EncodeDate(Year1*100+Year2,Month,Day)
+ EncodeTime(Hour,Min,Sec,0);//微秒为零
except
ACardUse.EnterTime := 0;
Result := -1;
end;
end;
mCommand.Free;
mBottomMsg.Free;
//===============第八区
//如果没有交费,不读第八区
if (ACardUse.LeaveAddr1 <> 'FF') or (ACardUse.LeaveAddr2 <> 'FF') then
begin
mCommand := TCommand.Create('B3B3B3 03 FC 0A 08 XX');
mBottomMsg := TBottomMsg.Create();
mCounter := 0 ;
while mCounter < TRY_TIMES do
begin
FMSComm.Output := mCommand.FBuffer;
Sleep(WAIT_TIME);
if FMSComm.InBufferCount >= 17 then
begin
//将OLE变量付值给树组
SetLength(mBuf,FMSComm.InBufferCount);
mBuf := FMSComm.Input;
mBottomMsg.SetBuffer(mBuf);
//分析应答数据
if mBottomMsg.GetPosStr(7) = '00' then break;
end;
Inc(mCounter);
end;
//放弃通信
if mCounter >= TRY_TIMES then
begin
Result := -1 ;
Exit;
end
else begin
try
//解析时间
Year1 := StrToInt(mBottomMsg.GetPosStr(9));
Year2 := StrToInt(mBottomMsg.GetPosStr(10));
Month := StrToInt(mBottomMsg.GetPosStr(11));
Day := StrToInt(mBottomMsg.GetPosStr(12));
Hour := StrToInt(mBottomMsg.GetPosStr(13));
Min := StrToInt(mBottomMsg.GetPosStr(14));
Sec := StrToInt(mBottomMsg.GetPosStr(15));
ACardUse.LeaveTime := EncodeDate(Year1*100+Year2,Month,Day)
+ EncodeTime(Hour,Min,Sec,0);//微秒为零
except
ACardUse.LeaveTime := 0;
Result := -1;
end;
end;
mCommand.Free;
mBottomMsg.Free;
end; //不读第八区
Result := 1;
end;
procedure TCardReader.SetAddress(Address: string);
begin
FAddr1 := Copy(Address,1,2);
FAddr2 := Copy(Address,3,2);
end;
function TCardReader.WriteArea(Area:integer;AContent: string): integer;
var
mCounter : integer;
mCommand : TCommand;
mBottomMsg : TBottomMsg;
mBuf: array of byte;
mStr: string;
begin
//检查写入内容长度
Assert(Length(AContent)=16,'卡写入区非法。');
//构造上位机报文
mStr := 'B3B3B3 0b F4 0B ' + IntToHex(Area,2) + AContent + 'XX';
mCommand := TCommand.Create(mStr);
//构造下位机应答信息类,准备接收下位机消息
mBottomMsg := TBottomMsg.Create();
//通信次数计数器
mCounter := 0 ;
while mCounter < TRY_TIMES do
begin
//输出上位机报文
FMSComm.Output := mCommand.FBuffer;
//等待下位机响应
Sleep(WAIT_TIME);
if FMSComm.InBufferCount >= 8 then
begin
//将OLE变量付值给树组
SetLength(mBuf,FMSComm.InBufferCount);
//检查上传报文长度
mBuf := FMSComm.Input;
//读取上传报文
mBottomMsg.SetBuffer(mBuf);
//分析应答数据
if mBottomMsg.GetPosStr(7) = '00' then break;
end;
Inc(mCounter);
end;
//放弃通信
if mCounter >= TRY_TIMES then
begin
Result := -1 ;
Exit;
end
else begin
Result := 1; //
end;
mCommand.Free;
mBottomMsg.Free;
end;
function TCardReader.WriteAddr(EnterAddr1,EnterAddr2,
LeaveAddr1,LeaveAddr2: string): integer;
var
mCommand : TCardCommand ;
mStr: string;
begin
Assert(Length(EnterAddr1)=2,'卡写入离开地址错误。');
Assert(Length(EnterAddr2)=2,'卡写入离开地址错误。');
Assert(Length(LeaveAddr1)=2,'卡写入离开地址错误。');
Assert(Length(LeaveAddr2)=2,'卡写入离开地址错误。');
mStr := EnterAddr1 + EnterAddr2 + LeaveAddr1 + LeaveAddr2;
mStr := mStr + '00 00 00 XX';
mCommand := TCardCommand.Create(mStr);
mStr := mCommand.GetStrBuffer();
Result := WriteArea(5,mStr);
mCommand.Free;
end;
function TCardReader.WriteLeaveTime(ADateTime: TDateTime): integer;
var
Year1,Year2,Month,Day,Hour,Min,Sec: word;
mStr: string;
mCommand : TCommand;
begin
DecodeDate(ADateTime,Year1,Month,Day);
DecodeTime(ADateTime,Hour,Min,Sec,Year2);
Year2 := Year1 mod 100;
Year1 := Year1 div 100;
mStr := IntToStr2(Year1)
+IntToStr2(Year2)
+IntToStr2(Month)
+IntToStr2(Day)
+IntToStr2(Hour)
+IntToStr2(Min)
+IntToStr2(Sec)
+'XX';
mCommand := TCardCommand.Create(mStr);
Result := WriteArea(8,mCommand.GetStrBuffer());
mCommand.Free;
end;
{ TCardCommand }
function TCardCommand.CalCheck: integer;
var
mByte : byte ;
i : integer;
mStr : string;
begin
//校验位已经付值
if not IsBufferPosToken(FLen) then
begin
Result := 0;
Exit;
end;
try
mByte := $00;
//从第六位开始计算校验位
for i := 6 to FLen-1 do
begin
mByte := mByte xor StrToInt('$' + Copy(FStrBuffer,i*2-1,2));
end;
mStr := IntToHex(mByte,2);
FStrBuffer[FLen*2-1] := mStr[1];
FStrBuffer[FLen*2] := mStr[2];
except
Result := -1;
Exit;
end;
Result := 1;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -