⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cabinetcontroler.~pas

📁 自己用API编写的端口通讯
💻 ~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 + -