串口在delphi中不起作用

时间:2011-11-01 14:03:15

标签: delphi serial-port hyperterminal

我在Delphi中创建一个简单的程序,使用2个参数通过COM端口发送字符,第一个参数是端口号,第二个参数是要发送的字符。因此,如果我将其保存为p.exe,“p.exe 20 A”将通过COM20发送“A”。

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;

我还使用具有相同COM编号的超级终端baudrate = 9600,flow_control = none并且它给出相同的结果。这个角色送得很好。 问题是,每次登录到我的Windows XP之前,我都无法运行我的程序(p.exe)之前执行以下步骤:     通过超级终端连接到指定的COM,     断开它。 然后我的可执行文件可以运行。否则,就像你在同一个COM中运行两个超级终端会话一样,它将无法工作。有人提示这个吗?我的代码中遗漏了什么吗?

2 个答案:

答案 0 :(得分:4)

我的代码中没有看到任何设置内容。所以,也许你依赖于运行HyperTerminal的副作用,为你“填充”端口。看看这篇文章,他们经历了那些东西:波特,奇偶校验等。

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

这似乎是一个完整的例子。看看你是否可以使用它,并作为构建的基础。

答案 1 :(得分:3)

您需要使用setcommstate来设置波特率和流量控制。

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;

使用

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