串口在delphi中不起作用

发布于 2024-12-12 19:27:05 字数 1258 浏览 6 评论 0原文

我正在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 中运行两个超级终端会话一样,它将无法工作。有人对此有任何提示吗?我的代码中遗漏了什么吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

別甾虛僞 2024-12-19 19:27:05

我在您的代码中没有看到任何设置内容。因此,也许您正在依赖运行超级终端的副作用来为您“启动”端口。看看这篇文章,他们介绍了这些内容:波特率、奇偶校验等。

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

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

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.

无力看清 2024-12-19 19:27:05

您需要使用 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;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文