首页  编辑  

Delphi一个操作串口的例子

Tags: /超级猛料/Hardware.硬件相关/其它硬件/   Date Created:

Delphi 一个操作窗口的例子

Title: Access the serial port in Windows XP

Author: Tomas Rutkauskas

Product: Delphi 4.x (or higher)

Post Date: 11/14/2002

Problem/Question/Abstract:

How I do to access the serial or paralell port in Windows XP?

Answer:

The example below sends a char 'R' to the port, then reads a line until CR or LF is encountered, then processes a line via ParseData. Then all is repeated until Terminated is True.

procedure ProcessCOMPortData(FPortName: string);

var

 LPortHandle: THandle;

 LInBuffer: array[0..1023] of Char;

 LBytesWritten, LBytesRead: Cardinal;

 LOutBuffer: Char;

 LOverlapped: TOverlapped;

 LEvent: TEvent;

 LOldCommTimeouts, LCommTimeouts: TCommTimeouts;

 LPCommConfig: PCommConfig;

 LCommConfig: TCommConfig;

 CommConfigSize: Cardinal;

 LEOL: Boolean;

 LIndex: Integer;

begin

 ZeroMemory(@LOverlapped, SizeOf(TOverlapped));

 ZeroMemory(@LCommTimeouts, SizeOf(TCommTimeouts));

 ZeroMemory(@LCommConfig, SizeOf(TCommConfig));

 LPortHandle := INVALID_HANDLE_VALUE;

 LEvent := nil;

 LPCommConfig := nil;

 try

   CommConfigSize := 0;

   LPCommConfig := @LCommConfig;

   GetDefaultCommConfig(PChar(FPortName), LPCommConfig^, CommConfigSize);

   GetMem(LPCommConfig, CommConfigSize);

   GetDefaultCommConfig(PChar(FPortName), LPCommConfig^, CommConfigSize);

   LEvent := TEvent.Create(nil, True, False, '');

   LOverlapped.hEvent := LEvent.Handle;

   LPortHandle := CreateFile(PChar(FPortName), GENERIC_READ or GENERIC_WRITE, 0,

     nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

   if (LPortHandle = INVALID_HANDLE_VALUE) then

     Exit;

   SetCommConfig(LPortHandle, LPCommConfig^, CommConfigSize);

   GetCommTimeouts(LPortHandle, LOldCommTimeouts);

   SetCommTimeouts(LPortHandle, LCommTimeouts);

   while not Terminated do

   begin

     PurgeComm(LPortHandle, PURGE_TXCLEAR or PURGE_RXCLEAR or

       PURGE_RXABORT or PURGE_TXABORT);

     LOutBuffer := 'R';

     WriteFile(LPortHandle, LOutBuffer, Length(LOutBuffer), LBytesWritten,

       @LOverlapped);

     GetOverlappedResult(LPortHandle, LOverlapped, LBytesWritten, True);

     if LBytesWritten = 1 then

     begin

       ZeroMemory(@LInBuffer, SizeOf(LInBuffer));

       ReadFile(LPortHandle, LInBuffer[0], 1, LBytesRead, @LOverlapped);

       case LEvent.WaitFor(50) of

         wrSignaled:

           begin

             GetOverlappedResult(LPortHandle, LOverlapped, LBytesRead, True);

             LEOL := False;

             LIndex := LBytesRead;

             while not LEOL and (LIndex < SizeOf(LInBuffer)) do

             begin

               ReadFile(LPortHandle, LInBuffer[LIndex], 1, LBytesRead, @LOverlapped);

               GetOverlappedResult(LPortHandle, LOverlapped, LBytesRead, True);

               LEOL := (LInBuffer[LIndex] = #$0A) or (LInBuffer[LIndex] = #$0D);

               Inc(LIndex);

             end;

             try

               ParseData(LInBuffer);

             except

             end;

           end;

         wrTimeout, wrAbandoned, wrError:

           begin

             Sleep(100);

           end;

       end;

     end;

   end;

 finally

   SetCommTimeouts(LPortHandle, LOldCommTimeouts);

   CloseHandle(LPortHandle);

   FreeAndNil(LEvent);

   if Assigned(LPCommConfig) then

     FreeMem(LPCommConfig);

 end;

end;