📄 cabinetcontroler.~pas
字号:
unit CabinetControler;
interface
uses
Windows,Dialogs,SysUtils,SyncObjs;
type
DiskBoxOpenState= array [0..15] of integer;
TCabinetControler = class
private
FDiskBoxIndex:integer; //盒子编号
FCabinetAddress:integer; //柜子地址
FStoreUnitIndex:integer; //单元格编号
FDiskState:DiskBoxOpenState; //抽屉开关状态
FComEvent:TSimpleEvent; //事件
FComEventQuery:TSimpleEvent; //查询事件
FComCabinet:THandle; //串口句柄
FReady:Boolean;
function InputQueryEx():Boolean; //查询输入,使用事件方式
function InputQuery( ):Boolean; //查询输入
function InputOpen( ):Boolean; //打开
function InitPort(InterfaceName:string ):Boolean; //初始化串口句柄
public
constructor Create(ValSpName: String);
Destructor Destroy; override;
function OpenDiskBox(DiskBoxIndex,DiskCabinetAddress:integer):boolean;
function LighterStoreUnit(CabinetAddress,DiskBoxIndex,StoreUnitIndex:integer):boolean;
function GetIsDiskBoxOpen(CabinetAddress:integer;var OutState:DiskBoxOpenState):Boolean;
end;
implementation
{ TCabinetControler }
constructor TCabinetControler.Create(ValSpName: String);
begin
inherited Create;
Self.InitPort(ValSpName);
end;
destructor TCabinetControler.Destroy;
begin
if Self.FComCabinet <> INVALID_HANDLE_VALUE then
begin
CloseHandle(Self.FComCabinet);
end;
self.FComEventQuery.Destroy;
self.FComEventQuery:=nil;
self.FComEvent.Destroy;
self.FComEvent:=nil;
inherited;
end;
function TCabinetControler.GetIsDiskBoxOpen(CabinetAddress:integer;
var OutState:DiskBoxOpenState): Boolean;
begin
result:=false;
Self.FCabinetAddress:=CabinetAddress;
if not (Self.InputQueryEx()) then
exit;
// if not (self.InputQuery( )) then
// exit;
OutState:=Self.FDiskState;
result:=True;
//返回值待商议
end;
//InterFaceName为串口名称:COM1或COM2;
function TCabinetControler.InitPort(InterfaceName:string): Boolean;
var
ValDCB: TDCB;
ValTimeOuts: TCommTimeouts;
begin
result:=False;
FComEvent:=TSimpleEvent.Create;
FComEventQuery:=TSimpleEvent.Create;
//打开Com端口
// FComCabinet:=CreateFile(PChar('\\.\'+InterfaceName),
// GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,
// 0,0);
FComCabinet:=CreateFile(PChar('\\.\'+InterfaceName),
GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,0);
if (FComCabinet=INVALID_HANDLE_VALUE) then
begin
ShowMessage('初始化COM串口失败');
exit;
end;
//设置Com状态
if GetCommState(Self.FComCabinet, ValDCB) then
begin
{利国 VAS9002A 通信协议:
8 data bits, 1 stop bit, and no parity}
ValDCB.BaudRate := CBR_9600;
ValDCB.ByteSize := 8;
ValDCB.StopBits := ONESTOPBIT;
ValDCB.Parity := SPACEPARITY;
// ValDCB.Flags := 1;
if not SetCommState(Self.FComCabinet, ValDCB) then
exit;
end
else
begin
exit;
end;
//设置等待时间
ValTimeOuts.ReadIntervalTimeout := 300;
ValTimeOuts.ReadTotalTimeoutMultiplier := 300;
ValTimeOuts.ReadTotalTimeoutConstant := 600;
ValTimeOuts.WriteTotalTimeoutMultiplier := 100;
ValTImeOuts.WriteTotalTimeoutConstant := 100;
if SetCommTimeOuts(Self.FComCabinet, ValTimeOuts) then
Self.FReady := true;
result:=True;
end;
function TCabinetControler.InputOpen:Boolean;
var
tempOL:TOverlapped;
SendBuff:array[0..2] of Byte;
SendBytes:DWORD;
begin
result:=False;
if ((Self.FComCabinet=INVALID_HANDLE_VALUE) and Self.FReady) then
begin
ShowMessage('设备没准备好');
exit;
end;
//初始化tempOL;
ZeroMemory(@tempOL, Sizeof(TOverlapped));
tempOL.Internal:=0;
tempOL.Offset:=0;
tempOL.OffsetHigh:=0;
tempOL.hEvent:=self.FComEvent.Handle;
self.FComEvent.ResetEvent;
//发送的字节
//保留位为1
SendBuff[0]:= $40 or Byte(Self.FCabinetAddress);
SendBuff[1]:= $A0 or Byte(Self.FDiskBoxIndex);
SendBuff[2]:= $C0 or Byte(self.FStoreUnitIndex);
// if (self.FStoreUnitIndex=0) then
// begin
// SendBuff[2]:=$55 or Byte(self.FStoreUnitIndex);
// end
// else
// begin
// SendBuff[2]:= $c0 or Byte(Self.FStoreUnitIndex);
// end;
PurgeComm(Self.FComCabinet, PURGE_TXCLEAR or PURGE_RXCLEAR
or PURGE_TXABORT or PURGE_RXABORT);
WriteFile(self.FComCabinet,SendBuff[0],1,SendBytes,@tempOL);
if Self.FComEvent.WaitFor(500)=wrSignaled then
begin
Self.FComEvent.ResetEvent;
// result:=True;
end
else
begin
ShowMessage('打开柜子超时');
exit;
end;
WriteFile(self.FComCabinet,SendBuff[1],1,SendBytes,@tempOL);
if Self.FComEvent.WaitFor(500)=wrSignaled then
begin
Self.FComEvent.ResetEvent;
// result:=True;
end
else
begin
ShowMessage('打开柜子超时');
exit;
end;
WriteFile(self.FComCabinet,SendBuff[2],1,SendBytes,@tempOL);
if Self.FComEvent.WaitFor(500)=wrSignaled then
begin
Self.FComEvent.ResetEvent;
// result:=True;
end
else
begin
ShowMessage('打开柜子超时');
exit;
end;
result:=True;
PurgeComm(Self.FComCabinet, PURGE_TXCLEAR or PURGE_RXCLEAR
or PURGE_TXABORT or PURGE_RXABORT);
end;
function TCabinetControler.InputQuery( ):Boolean;
var
tempOL : TOverlapped;
SendBuff: Byte;
ReciveBuff: array[0..1] of Byte;
SendBytes: DWORD;
// fSuccess:BOOL;
// dwEvtMask:DWORD;
begin
result:=False;
if ((Self.FComCabinet=INVALID_HANDLE_VALUE) and self.FReady) then
begin
ShowMessage('设备没准备好');
exit;
end;
Zeromemory(@tempOL,sizeof(TOverlapped));
tempOL.Internal:=0;
tempOL.Offset:=0;
tempOL.OffsetHigh:=0;
tempOL.hEvent:=self.FComEvent.Handle;
self.FComEvent.ResetEvent;
PurgeComm(Self.FComCabinet, PURGE_TXCLEAR or PURGE_RXCLEAR
or PURGE_TXABORT or PURGE_RXABORT);
//发送查询数据
SendBuff:= Byte(Self.FCabinetAddress);
WriteFile(self.FComCabinet,SendBuff,1,SendBytes,@tempOL);
if self.FComEvent.WaitFor(3000)=wrSignaled then
begin
self.FComEvent.ResetEvent;
end
else
begin
ShowMessage('发送请求超时');
exit;
end;
//接收数据
ReciveBuff[0]:=0;
ReciveBuff[1]:=0;
PurgeComm(Self.FComCabinet, PURGE_TXCLEAR or PURGE_RXCLEAR
or PURGE_TXABORT or PURGE_RXABORT);
ReadFile(self.FComCabinet,ReciveBuff[0],2,SendBytes,@tempOL);
if (self.FComEvent.WaitFor(3000)=wrSignaled) then
begin
self.FComEvent.ResetEvent;
//对接受的数据进行处理
Self.FDiskState[7]:=ReciveBuff[0] and $80;
Self.FDiskState[6]:=ReciveBuff[0] and $40;
Self.FDiskState[5]:=ReciveBuff[0] and $20;
Self.FDiskState[4]:=ReciveBuff[0] and $10;
Self.FDiskState[3]:=ReciveBuff[0] and $8;
Self.FDiskState[2]:=ReciveBuff[0] and $4;
Self.FDiskState[1]:=ReciveBuff[0] and $2;
Self.FDiskState[0]:=ReciveBuff[0] and $1;
Self.FDiskState[15]:=ReciveBuff[1] and $80;
Self.FDiskState[14]:=ReciveBuff[1] and $40;
Self.FDiskState[13]:=ReciveBuff[1] and $20;
Self.FDiskState[12]:=ReciveBuff[1] and $10;
Self.FDiskState[11]:=ReciveBuff[1] and $8;
Self.FDiskState[10]:=ReciveBuff[1] and $4;
Self.FDiskState[9]:=ReciveBuff[1] and $2;
Self.FDiskState[8]:=ReciveBuff[1] and $1;
result:=true;
end
else
begin
ShowMessage('接收请求超时间');
exit;
end;
// }
PurgeComm(Self.FComCabinet, PURGE_TXCLEAR or PURGE_RXCLEAR
or PURGE_TXABORT or PURGE_RXABORT);
end;
//false——点亮失败
function TCabinetControler.InputQueryEx: Boolean;
var
// tempOL : TOverlapped;
tempOL : POverlapped;
SendBuff: Byte;
ReciveBuff: array[0..1] of Byte;
SendBytes: DWORD;
// fSuccess:BOOL;
dwEvtMask:DWORD;
begin
result:=False;
//初始化
dwEvtMask:=0;
SendBuff:= Byte(Self.FCabinetAddress);
ReciveBuff[0]:=0;
ReciveBuff[1]:=0;
GetMem(tempOL,sizeof(_OVERLAPPED));
Zeromemory(tempOL,sizeof(_OVERLAPPED));
tempOL.Internal:=0;
tempOL.Offset:=0;
tempOL.OffsetHigh:=0;
tempOL.hEvent:=self.FComEventQuery.Handle;
self.FComEventQuery.ResetEvent;
if ((Self.FComCabinet=INVALID_HANDLE_VALUE) and self.FReady) then
begin
ShowMessage('设备没准备好');
exit;
end;
PurgeComm(Self.FComCabinet, PURGE_TXCLEAR or PURGE_RXCLEAR
or PURGE_TXABORT or PURGE_RXABORT);
WriteFile(self.FComCabinet,SendBuff,1,SendBytes,tempOL);
SetCommMask(self.FComCabinet,0);
SetCommMask(self.FComCabinet, EV_RXCHAR);
WaitCommEvent(self.FComCabinet, dwEvtMask, tempOL);
if (self.FComEventQuery.WaitFor(500)=wrSignaled) then
begin
if ((dwEvtMask and EV_RXCHAR)<>0) then
begin
// To do.
// PurgeComm(Self.FComCabinet, PURGE_TXCLEAR or PURGE_RXCLEAR
// or PURGE_TXABORT or PURGE_RXABORT);
ReadFile(self.FComCabinet,ReciveBuff[0],2,SendBytes,tempOL);
if (self.FComEventQuery.WaitFor(1000)=wrSignaled) then
// if (self.FComEvent.WaitFor(3000)=wrSignaled) then
begin
self.FComEventQuery.ResetEvent;
// self.FComEvent.ResetEvent;
//对接受的数据进行处理
Self.FDiskState[7]:=ReciveBuff[0] and $80;
Self.FDiskState[6]:=ReciveBuff[0] and $40;
Self.FDiskState[5]:=ReciveBuff[0] and $20;
Self.FDiskState[4]:=ReciveBuff[0] and $10;
Self.FDiskState[3]:=ReciveBuff[0] and $8;
Self.FDiskState[2]:=ReciveBuff[0] and $4;
Self.FDiskState[1]:=ReciveBuff[0] and $2;
Self.FDiskState[0]:=ReciveBuff[0] and $1;
Self.FDiskState[15]:=ReciveBuff[1] and $80;
Self.FDiskState[14]:=ReciveBuff[1] and $40;
Self.FDiskState[13]:=ReciveBuff[1] and $20;
Self.FDiskState[12]:=ReciveBuff[1] and $10;
Self.FDiskState[11]:=ReciveBuff[1] and $8;
Self.FDiskState[10]:=ReciveBuff[1] and $4;
Self.FDiskState[9]:=ReciveBuff[1] and $2;
Self.FDiskState[8]:=ReciveBuff[1] and $1;
result:=true;
end
else
begin
ShowMessage('接收请求超时间');
exit;
end;
end;
end
else
begin
SetCommMask(self.FComCabinet,0);
ShowMessage('接收超时间');
exit;
end;
PurgeComm(Self.FComCabinet, PURGE_TXCLEAR or PURGE_RXCLEAR
or PURGE_TXABORT or PURGE_RXABORT);
// Self.FComEventQuery.ResetEvent;
// Self.FComEvent.ResetEvent;
end;
function TCabinetControler.LighterStoreUnit(CabinetAddress, DiskBoxIndex,
StoreUnitIndex: integer): boolean;
begin
result:=False;
if (FReady=False) then
begin
ShowMessage('设备没准备好');
exit;
end;
Self.FCabinetAddress:=CabinetAddress;
Self.FDiskBoxIndex:=DiskBoxIndex;
if (StoreUnitIndex>31) then
begin
Self.FStoreUnitIndex:=StoreUnitIndex;
end
else
begin
Self.FStoreUnitIndex:=(StoreUnitIndex-31)*(-1);
end;
// Self.FStoreUnitIndex:=StoreUnitIndex;
if (InputOpen) then
result:=True
else
result:=False;
end;
function TCabinetControler.OpenDiskBox(DiskBoxIndex,
DiskCabinetAddress: integer): boolean;
begin
result:=False;
if not (self.FReady) then
begin
ShowMessage('设备没准备好');
exit;
end;
Self.FCabinetAddress:=DiskCabinetAddress;
Self.FDiskBoxIndex:=DiskBoxIndex;
Self.FStoreUnitIndex:=1;
if (InputOpen) then
result:=True
else
result:=False;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -