3

我在 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 中运行两个超级终端会话一样,它不会工作。有人对此有提示吗?我错过了代码中的任何内容吗?

4

2 回答 2

4

我在您的代码中看不到任何设置内容。因此,也许您依赖运行 HyperTerminal 的副作用来为您“启动”端口。看看这篇文章,他们在其中经历了那些东西:波特、奇偶校验等。

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

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

于 2011-11-01T14:27:22.937 回答
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;
于 2011-11-01T14:40:36.293 回答