Access the serial port in Windows XP (Views: 29)
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; |