serial port won't work in delphi

6.3k Views Asked by At

I'm creating a simple program in Delphi, to send character through COM port using 2 parameters, the first parameter is the port number and the second parameter is the character to be sent. So if i save it as p.exe, "p.exe 20 A" will send "A" through COM20.

try
   PhoneNumber := ParamStr(2);

   if(StrToInt(ParamStr(1))>=10)then
   CommPort := '\\.\COM'+ParamStr(1)
   else
   CommPort := 'COM'+ParamStr(1);
   hCommFile := CreateFile(PChar(CommPort),
                          GENERIC_WRITE,
                          0,
                          nil,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
                          0);
   if hCommFile=INVALID_HANDLE_VALUE then begin
      ShowMessage('Unable to open '+ CommPort);
   end;
  if WriteFile(hCommFile, PChar(PhoneNumber)^, Length(PhoneNumber),NumberWritten, nil)=false then
    showmessage('Unable to send');
  PurgeComm(hCommFile,PURGE_TXCLEAR);
  FlushFileBuffers(hCommFile);
  CloseHandle(hCommFile);
  Application.Terminate;
except
  PurgeComm(hCommFile,PURGE_TXCLEAR);
  FlushFileBuffers(hCommFile);
  Application.Terminate;
end;

And I also using hyperterminal with the same COM number baudrate=9600, flow_control=none and it gives the same result. The character sent well. The problem is, I cant run my program (p.exe) before I do the following steps each time i logged on to my Windows XP: Connect through hyperterminal to the designated COM, disconnect it. then my executable can be run. Otherwise, just like you run two session of hyperterminal in the same COM, it wouldn't work. Anybody got a hint bout this? Did I miss anything in my code?

2

There are 2 best solutions below

0
On

I don't see any setup stuff in your code. So maybe you're relying on a side-effect of running HyperTerminal that "primes" the port for you. Have a look at this article where they go through that stuff: baud, parity, etc..

http://www.delphi-central.com/serial.aspx

It seems to be a full working example. See if you can get that working, and use as a base to build from.

3
On

You need to use setcommstate for setup baud rate and flow control.

Function OpenPort( Var fHandle: THandle; fPort: String): Boolean;
Const
 RxBufferSize       = 32;
 TxBufferSize       = 32;
Var
 dcb                : TDCB;
 tms                : TCOMMTIMEOUTS;
Begin
 Result := False;
 Try
  If fHandle <> INVALID_HANDLE_VALUE Then
   CloseHandle( fhandle );
 Except
 End;
 Try
  //fport must be \\.\ URN format
  fhandle := CreateFile( PChar( fPort ), GENERIC_WRITE or GENERIC_READ, FILE_SHARE_WRITE ,
                         Nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
  If ( fhandle = INVALID_HANDLE_VALUE ) Then
   Begin
    result := false;
    exit;
   End;
  SetupComm( fhandle, RxBufferSize, TxBufferSize );

  If pos( 'LPT', fPort ) > 0 Then
   //
  Else
   Begin
    GetCommState( fhandle, dcb );
    dcb.DCBlength := sizeof( dcb );
    dcb.BaudRate := cbr_9600;
    dcb.Flags := 1;                     // binary...
    if dtr_rts then
    begin
     dcb.flags := dcb.Flags Or $20;      //DTR HANDSHAKE
     dcb.Flags := dcb.Flags Or $1000;    //rts handshake
     dcb.Flags := dcb.Flags Or 4;        //Outx_CtsFlow
     dcb.Flags := dcb.Flags Or 8;        //Outx_DsrFlow
     dcb.Flags := dcb.Flags Or $40;      //DsrSensitivity
     //dcb.Flags := dcb.Flags or $100;//Outx_XonXoffFlow
     //dcb.Flags := dcb.Flags or $200;//Inx_XonXoffFlow
    end;
    dcb.ByteSize := 8;
    dcb.Parity := EVENPARITY;
    dcb.StopBits := ONESTOPBIT;
    SetCommState( fhandle, dcb );
    GetCommTimeouts( fhandle, tms );
    tms.ReadIntervalTimeout := 100;//you can change multipler values with
    tms.ReadTotalTimeoutMultiplier := 100;//your values
    tms.ReadTotalTimeoutConstant := 1;
    SetCommTimeOuts( fhandle, tms );
   End;
  EscapeCommFunction( fhandle, CLRRTS Or CLRDTR Or SETRTS Or SETDTR );//for handshaking
  Result := True;
 Except
  Result := False;
 End;
End;

usage

var 
    fporthandle:thandle;
   begin
    if OpenPort(fporthandle,'\\.\com1') then
      try
       writefile(fporthandle,pchar('TEST')...);
      finally
        closehandle(fporthandle);
      end;