这次把源代码贴上来:
设置并创建一个串口句柄:
try
hComm := CreateFile(PChar(strCommName),
GENERIC_READ or GENERIC_WRITE,
0, //Exclusive Access
nil, //No Security Attribute
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0); //Template File
if hComm=INVALID_HANDLE_VALUE then
raise Exception.Create(strCommName+' Open Failed!');
except
ShowMessage(strCommName+' Open Failed!');
Exit;
end;
try
if not SetCommMask(hComm, EV_RXCHAR) then
raise Exception.Create(strCommName+' Setup Step 1 Failed!');
if not SetupComm(hComm, 4*nBuffLen, 4*nBuffLen) then
raise Exception.Create(strCommName+' Setup Step 1 Failed!');
if not PurgeComm(hComm, PURGE_RXABORT or PURGE_RXCLEAR or
PURGE_TXABORT or PURGE_TXCLEAR) then
raise Exception.Create(strCommName+' Setup Step 1 Failed!');
cto.ReadIntervalTimeout := $ffffffff;
cto.ReadTotalTimeoutMultiplier := 0;
cto.ReadTotalTimeoutConstant := 1000; //1 second
cto.WriteTotalTimeoutMultiplier := 2*CBR_9600 div CBR_19200;
cto.WriteTotalTimeoutConstant := 0;
if not SetCommTimeOuts(hComm, cto) then
raise Exception.Create(strCommName+' Setup Step 1 Failed!');
except
CloseHandle(hComm);
ShowMessage(strCommName+' Setup Step 1 Failed!');
Exit;
end;
try
dcb.DCBlength := SizeOf(TDCB);
if not GetCommState(hComm, dcb) then
raise Exception.Create(strCommName+' Setup Step 2 Failed!');
dcb.DCBlength := SizeOf(TDCB);
dcb.BaudRate := CBR_19200;
dcb.ByteSize := 8;
dcb.Parity := NOPARITY;
dcb.StopBits := ONESTOPBIT;
dcb.XonChar := Chr($11); //Ctrl_Q
dcb.XoffChar := Chr($13); //Ctrl_S
dcb.ErrorChar := Chr(0);
dcb.XonLim := 100;
dcb.XoffLim := 100;
dcbFlag := 1; //Binary must be True
dcbFlag := dcbFlag or 2; //Parity Check True
dcbFlag := dcbFlag or 4; //FOutxCtsFlowCtrl
dcbFlag := dcbFlag or 8; //FOutxDsrFlowCtrl
dcbFlag := dcbFlag or $20; //DtrHandShake
dcbFlag := dcbFlag or $1000; //RtsEnable
dcbFlag := dcbFlag or $800; //Ignore NULL Char
dcb.Flags := dcbFlag;
if not SetCommState(hComm, dcb) then
raise Exception.Create(strCommName+' Setup Step 2 Failed!');
bConnected := True;
except
CloseHandle(hComm);
ShowMessage(strCommName+' Setup Step 2 Failed!');
Exit;
end;
EscapeCommFunction(hComm, SETDTR);
EscapeCommFunction(hComm, SETRTS);
thdDaemon := TCommDaemonThd.Create;
TCommDaemonThd部分:
procedure TCommDaemonThd.Execute;
var
dwEventMask : DWORD;
nLength : integer;
begin
SetCommMask(frmMain.hComm, EV_RXCHAR);
while frmMain.bConnected do
begin
dwEventMask := 0;
WaitCommEvent(frmMain.hComm, dwEventMask, nil);
if ( (dwEventMask and EV_RXCHAR)=EV_RXCHAR ) then //Char Received
repeat
nLength := ReadComm;
Synchronize(ShowSuccess);
until nLength=0;
end;
SetEvent(frmMain.eveClose);
end;
constructor TCommDaemonThd.Create;
begin
FreeOnTerminate := True;
inherited Create(False);
end;
procedure TCommDaemonThd.ShowSuccess;
begin
frmMain.mStatus.Lines.Append(strFile+' Received!');
end;
function TCommDaemonThd.ReadComm;
var
dwErr, dwError, dwLength : DWORD;
commStat : TComStat;
begin
ClearCommError(frmMain.hComm, dwErr, @commStat);
dwLength := min( nBuffLen, commStat.cbInque);
if dwLength>0 then
if not ReadFile(frmMain.hComm, strFile, dwLength, dwLength, @frmMain.readOl) then
begin
if GetLastError=ERROR_IO_PENDING then
begin
while not GetOverLappedResult(frmMain.hComm, frmMain.readOl, dwLength, TRUE) do
begin
dwErr := GetLastError;
if dwErr=ERROR_IO_INCOMPLETE then
continue
else begin
//Show Error
ClearCommError(frmMain.hComm, dwError, @commStat);
//Show Error
end;
end; //end while
end // end if GetLastError...
else begin
//Show Error
ClearCommError(frmMain.hComm, dwError, @commStat);
//Show Error
end;
end; //end if dwLength>0 , end if not ReadFile...
Result := dwLength;
end;
发送部分:
if bConnected then //In fact Always True
begin
strToSend := eSendFile.Text;
bWriteFile := WriteFile(hComm, strToSend, Length(strToSend)+1, dwLength, @writeOl);
if not bWriteFile then
begin
dwErr := GetLastError;
if dwErr=ERROR_IO_PENDING then
begin
while not GetOverLappedResult(hComm, writeOl, dwLength, TRUE) do
begin
dwErr := GetLastError;
if dwErr=ERROR_IO_INCOMPLETE then
continue
else begin
//Show Error
ClearCommError(hComm, dwError, @commStat);
//show Error
end;
end; //end while
//Lines below for debuging
GetCommModemStatus(hComm, dwMStat);
if (dwMStat and MS_DSR_ON)=0 then
mStatus.Lines.Append('DSR Low!')
else if (dwMStat and MS_CTS_ON)=0 then
mStatus.Lines.Append('CTS Low!')
else
mStatus.Lines.Append('Strange Error!');
//Lines Above for Debuging
end // end if GetLastError=...
else begin
//Show Error
ClearCommError(hComm, dwError, @commStat);
mStatus.Lines.Append('Error: '+IntToStr(dwError));
end;
end; //end if not bWriteFile
end; //end if bConnected
此外断开连接是正确的,就不贴了.
请大家分析一下吧,多谢了.