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