请教:有关用api多线程处理串口通讯时超时的问题 ( 积分: 100 )

  • 主题发起人 主题发起人 wdreamfly
  • 开始时间 开始时间
W

wdreamfly

Unregistered / Unconfirmed
GUEST, unregistred user!
用api多线程处理串口通讯,串口监视线程采用事件触发,是不是超时结构就没用了?我没定义超使结构,用的是WaitForSingleObject(os.hEvent,6000)=WAIT_TIMEOUT来处理是否读写超时。如果去掉串口线,第一次可以进入if WaitForSingleObject(os.hEvent,6000)=WAIT_TIMEOUT then
语句里,超时,发消息给主程序,然后,串口监视线程跳转到while receivedo
,继续执行到dwError := GetLastError();语句时,dwError=87,好像说参数不对。不知道该怎么修改了?能关于超时提点建议么?下面是我的串口监视线程,谢谢!
////通信监视线程
procedure CommWatchThread(var lpdwParam: DWORD);
var
dwTransfer, dwEvtMask, dwError: DWORD;
os: _OVERLAPPED;
bl,gl: boolean;
begin
os.hEvent := CreateEvent(nil,
TRUE,
FALSE,
nil);
comMask := SetCommMask(hCommDev, EV_RXCHAR or EV_TXEMPTY);
//设置监视的事件为接收到字符或发送缓冲区空

if comMask = True then
begin
while recievedo
begin
dwEvtMask := 0;
bl := WaitCommEvent(hCommDev, dwEvtMask, @os);
//查询所监视的通信事件是否
//已经发生
if bl = False then
begin
dwError := GetLastError();
if dwError = ERROR_IO_PENDING then
begin
// gl:=GetOverlappedResult(hCOmmDev, os, dwTransfer, true);
//若未监测到通信事件
// if gl=false then
begin
if WaitForSingleObject(os.hEvent,6000)=WAIT_TIMEOUT then
begin
OverTmCount:=OverTmCount+1;
//超时后主程序重发命令,五次后退出
if OverTmCount<5 then
SendMessage(Application.mainform.Handle, WM_COMMNOTIFY, hCommDev, 0) //处理超时的情况
else
begin
recieve:=false;
PurgeComm(hCommDev,PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR);
// showmessage('超时,退出');
end;
end;
end;
end;

end
else
//有事件,进行如下处理
begin
if (dwEvtMask and EV_RXCHAR) = EV_RXCHAR then
//判断是否为接收到字符事件
begin
WaitForSingleObject(postRecvEvent, $FFFFFFFF);
//等待接收事件句柄为有信号状态
ResetEvent(postRecvEvent);
//置接收事件句柄为无信号状态,以免接收
CommRecvNotify;
//调用接收到字符处理函数
setEvent(postRecvEvent);
continue;
//处理完接收字符,继续监测通信事件
end;
end;
if (dwEvtMask and EV_TXEMPTY) = EV_TXEMPTY then
//判断是否为发送缓冲区空事件
begin
WaitForSingleObject(postSendEvent, $FFFFFFFF);
//等待发送事件句柄为有
//信号状态
ResetEvent(postSendEvent);
//置发送事件句柄为无信号状态,,以免发送
//缓冲区被覆盖
CommSendNotify;
//调用发送缓冲区空处理函数
SetEvent(postSendEvent);
//置发送事件未有信号状态,以便进行下一次发送
continue;
//处理完,继续监测通信事件
end;

end;
end;
CloseHandle(os.hEvent);
end;
 
用api多线程处理串口通讯,串口监视线程采用事件触发,是不是超时结构就没用了?我没定义超使结构,用的是WaitForSingleObject(os.hEvent,6000)=WAIT_TIMEOUT来处理是否读写超时。如果去掉串口线,第一次可以进入if WaitForSingleObject(os.hEvent,6000)=WAIT_TIMEOUT then
语句里,超时,发消息给主程序,然后,串口监视线程跳转到while receivedo
,继续执行到dwError := GetLastError();语句时,dwError=87,好像说参数不对。不知道该怎么修改了?能关于超时提点建议么?下面是我的串口监视线程,谢谢!
////通信监视线程
procedure CommWatchThread(var lpdwParam: DWORD);
var
dwTransfer, dwEvtMask, dwError: DWORD;
os: _OVERLAPPED;
bl,gl: boolean;
begin
os.hEvent := CreateEvent(nil,
TRUE,
FALSE,
nil);
comMask := SetCommMask(hCommDev, EV_RXCHAR or EV_TXEMPTY);
//设置监视的事件为接收到字符或发送缓冲区空

if comMask = True then
begin
while recievedo
begin
dwEvtMask := 0;
bl := WaitCommEvent(hCommDev, dwEvtMask, @os);
//查询所监视的通信事件是否
//已经发生
if bl = False then
begin
dwError := GetLastError();
if dwError = ERROR_IO_PENDING then
begin
// gl:=GetOverlappedResult(hCOmmDev, os, dwTransfer, true);
//若未监测到通信事件
// if gl=false then
begin
if WaitForSingleObject(os.hEvent,6000)=WAIT_TIMEOUT then
begin
OverTmCount:=OverTmCount+1;
//超时后主程序重发命令,五次后退出
if OverTmCount<5 then
SendMessage(Application.mainform.Handle, WM_COMMNOTIFY, hCommDev, 0) //处理超时的情况
else
begin
recieve:=false;
PurgeComm(hCommDev,PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR);
// showmessage('超时,退出');
end;
end;
end;
end;

end
else
//有事件,进行如下处理
begin
if (dwEvtMask and EV_RXCHAR) = EV_RXCHAR then
//判断是否为接收到字符事件
begin
WaitForSingleObject(postRecvEvent, $FFFFFFFF);
//等待接收事件句柄为有信号状态
ResetEvent(postRecvEvent);
//置接收事件句柄为无信号状态,以免接收
CommRecvNotify;
//调用接收到字符处理函数
setEvent(postRecvEvent);
continue;
//处理完接收字符,继续监测通信事件
end;
end;
if (dwEvtMask and EV_TXEMPTY) = EV_TXEMPTY then
//判断是否为发送缓冲区空事件
begin
WaitForSingleObject(postSendEvent, $FFFFFFFF);
//等待发送事件句柄为有
//信号状态
ResetEvent(postSendEvent);
//置发送事件句柄为无信号状态,,以免发送
//缓冲区被覆盖
CommSendNotify;
//调用发送缓冲区空处理函数
SetEvent(postSendEvent);
//置发送事件未有信号状态,以便进行下一次发送
continue;
//处理完,继续监测通信事件
end;

end;
end;
CloseHandle(os.hEvent);
end;
 
后退
顶部