第一次用API操作串口,用起来没什么大问题,但总感觉不是很好,觉得有些隐患,大家看看我的代码,提提意见。
UINT __cdecl CComSnR::ReadData(LPVOID pParam)
{
CComSnR* sr = (CComSnR*)pParam;

DWORD dwEvnMask = 0;
WaitCommEvent(sr->m_hCom,&dwEvnMask,&sr->m_olWrite); //清除错误信息
COMSTAT ComStat;
DWORD dwErrorFlags;
ClearCommError(sr->m_hCom,&dwErrorFlags,&ComStat);
 
//向串口写数据
BOOL bWriteState;
DWORD dwBytesWritten = sr->m_nSendLen;
sr->start = GetTickCount();
int a = sr->m_nTimes + 1;
while(a--){
bWriteState = WriteFile(sr->m_hCom,sr->SendBuf,dwBytesWritten,&dwBytesWritten,&sr->m_olWrite); 
if(!bWriteState && ERROR_IO_PENDING == GetLastError()){
GetOverlappedResult(sr->m_hCom,&sr->m_olWrite,&dwBytesWritten,TRUE);
}
//延迟4毫秒等待下位机返回数据
Sleep(4); //开始读数据
DWORD dwBytesRead;
ClearCommError(sr->m_hCom,&dwErrorFlags,&ComStat);
dwBytesRead = sr->m_nRequireLen;
ReadFile(sr->m_hCom,sr->RecvBuf,dwBytesRead,&dwBytesRead,&sr->m_olRead);
int State = WaitForSingleObject(sr->m_olRead.hEvent,sr->m_nRequireLen + 40);
if(WAIT_OBJECT_0 == State){
if(OK == sr->CheckMsg()){
sr->end = GetTickCount();
return(0);
}
::MessageBox(sr->hWnd,_T("校验出错"),_T(" "),MB_OK);
}
//如果接收失败,清空缓冲区
PurgeComm(sr->m_hCom,PURGE_TXCLEAR | PURGE_RXCLEAR);
}
sr->m_nState = ERR_TIMEOUT; ::SendMessage(sr->hWnd,WM_TIMEOUT,0,0);
// ::MessageBox(sr->hWnd,_T("等待超时"),_T(" "),MB_OK);
  return(0);
}

解决方案 »

  1.   

    写和读倒是没什么问题,关键我这里有个while循环,是处理超时的,我没有用API自带的超时结构,而是另外的思路,就是我每一次请求数据后,在一定时间里没有读取到(或者读取到但未通过校验)数据就重新请求一次,我这个是自用的类,所以将发数据和写数据连在一起,不知道这样判断会不会有什么问题?还有,我看到网上很多的类都是主线程负责发数据,辅线程只负责监视数据的接收,我感觉那样也挺合理的,但是若想实现我这种超时机制是不是就不合适了?高手请发现意见啊。不要草草一句就完事(`^`)
      

  2.   

    前几天有一个项目也需要用串口, 我对串口以前根本没接触过。用cncomm完成的。。