异步方式同时打开moxa卡的串口有问题,数据读不出来。要用其他软件一一打开串口读到数据后,再启动我的程序才能读到数据.哪里错了?// BaseCommDevice.cpp: implementation of the CBaseCommDevice class.
//
//////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "BaseCommDevice.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////CBaseCommDevice::CBaseCommDevice()
{
 m_hComm = INVALID_HANDLE_VALUE;
 memset(m_Port,0,sizeof(m_Port));
 m_BaudRate=0;
 m_bOpened = FALSE;
 m_dwInBuf = 512;
 m_dwOutBuf = 512;
 dwID=0;
 hThreadHandle=NULL;
}CBaseCommDevice::~CBaseCommDevice()
{
CloseDevice();
}
void CBaseCommDevice::setPort(char *szPort)
{
 memset(m_Port,0,sizeof(m_Port));
 memcpy(m_Port,szPort,strlen(szPort));
}
char *CBaseCommDevice::getPort()
{
return m_Port;
}
void CBaseCommDevice::setBaudRate(int _BaudRate)
{
m_BaudRate=_BaudRate;
}
int  CBaseCommDevice::getBaudRate()
{
    return m_BaudRate;
}
bool CBaseCommDevice::OpenDevice()
{
ASSERT(m_BaudRate >= 110 || m_BaudRate <= 128000||strlen(m_Port)>0);
DCB dcb = {0};
    dcb.DCBlength = sizeof(dcb);
char lpDef[15];
wsprintf(lpDef, "%d,n,8,1", m_BaudRate);
    if( m_bOpened ) return true;
char szCom[20];
sprintf(szCom,"\\\\.\\%s",m_Port);
m_hComm = CreateFile(szCom, GENERIC_READ | GENERIC_WRITE,
             0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    if( m_hComm == INVALID_HANDLE_VALUE ) return false; FillMemory(&m_osReader, sizeof(OVERLAPPED), 0);
    FillMemory(&m_osWriter, sizeof(OVERLAPPED), 0);
    m_osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    m_osWriter.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    int byteUsedTime = 14400 / m_BaudRate +1;   COMMTIMEOUTS timeouts = {20 + byteUsedTime, byteUsedTime, 1000, byteUsedTime , 20};
   dcb.fParity = TRUE;
   dcb.fErrorChar = TRUE;
   dcb.ErrorChar = '~'; 
   if( m_osReader.hEvent == NULL || m_osWriter.hEvent == NULL
     || !SetCommTimeouts(m_hComm, &timeouts) 
     || !BuildCommDCB(lpDef, &dcb) 
     || !SetupComm(m_hComm, m_dwInBuf, m_dwOutBuf)) 
   {
     if( m_osReader.hEvent != NULL )CloseHandle( m_osReader.hEvent );
     if( m_osWriter.hEvent != NULL )CloseHandle( m_osWriter.hEvent );
     CloseHandle( m_hComm );
     return false;
   }
   m_bOpened = true;
   return m_bOpened;}
void CBaseCommDevice::CloseDevice()
{
if (m_osReader.hEvent != NULL) CloseHandle( m_osReader.hEvent );
if (m_osWriter.hEvent != NULL) CloseHandle( m_osWriter.hEvent );
if (m_hComm != NULL)CloseHandle( m_hComm );
m_bOpened = FALSE;
}
void CBaseCommDevice::PreOpenSetupQueue(DWORD dwInQueue, DWORD dwOutQueue)
{
m_dwInBuf = dwInQueue;
m_dwOutBuf = dwOutQueue;
}
BOOL CBaseCommDevice::SetupQueue(DWORD dwInQueue, DWORD dwOutQueue){if (m_hComm == NULL) return FALSE;m_dwInBuf = dwInQueue;m_dwOutBuf = dwOutQueue;return SetupComm(m_hComm, m_dwInBuf, m_dwOutBuf);}
BOOL CBaseCommDevice::ResetParity(char Parity)
{
if (m_hComm == NULL) return FALSE;
DCB dcb;
dcb.DCBlength = sizeof( DCB );
if (!GetCommState(m_hComm, &dcb)) return FALSE;
BYTE cParity;
Parity = tolower(Parity);
switch (Parity) {
case 'o':cParity = 1;break;
case 'e':cParity = 2;break;
case 'm':cParity = 3;break;
case 's':cParity = 4;break;
    default:cParity = 0;break;
}
dcb.Parity = cParity;
return SetCommState(m_hComm, &dcb);
}
BOOL CBaseCommDevice::SendData(LPCVOID lpBuf, DWORD dwToWrite)
{
TRACE("SSSSSSSSSSSSS 00\n"); 
if( !m_bOpened || m_hComm == NULL ) return FALSE;
DWORD dwWritten;
if (WriteFile(m_hComm, lpBuf, dwToWrite, &dwWritten, &m_osWriter)) return TRUE;
if (GetLastError() != ERROR_IO_PENDING)  return FALSE;
GetOverlappedResult(m_hComm, &m_osWriter, &dwWritten, TRUE);
TRACE("SSSSSSSSSSSSS 11\n"); 
return (dwToWrite == dwWritten);}
DWORD CBaseCommDevice::ReadData(LPVOID lpBuf, DWORD dwToRead)

TRACE("RRRRRRRRRRRR 00\n"); 
if( !m_bOpened || m_hComm == NULL ) return 0;
DWORD dwRead;
if (ReadFile(m_hComm, lpBuf, dwToRead, &dwRead, &m_osReader) ) return dwRead; 
if (GetLastError() != ERROR_IO_PENDING)  return 0;
if (WaitForSingleObject(m_osReader.hEvent, INFINITE) != WAIT_OBJECT_0 ) 
return 0;
if (!GetOverlappedResult(m_hComm, &m_osReader, &dwRead, FALSE) )
return 0;
TRACE("RRRRRRRRRRRR 11\n");  
return dwRead;}
void CBaseCommDevice::Start()
{
dwStopThread=0;
if(!m_bOpened)
{
PreOpenSetupQueue(BUFFLEN, BUFFLEN);

        if (!OpenDevice())
{
char buff[100];
sprintf(buff,"Open %s %d error",m_Port,m_BaudRate);
OnError(buff);
return ;
}
hThreadHandle=CreateThread(NULL,0,ReceiveDataThread,this,0,&dwID);
        OnAfterStartMonitor();
char buff[100];
sprintf(buff,"Open %s %d success",m_Port,m_BaudRate);
OnError(buff);
return;
}
char buff[100];
sprintf(buff,"Open %s %d already opened",m_Port,m_BaudRate);
OnError(buff);
return;
}
//停止监视
void CBaseCommDevice::Stop()
{
  dwStopThread=1;
  StopThread(hThreadHandle,dwID);
  CloseDevice();
}
DWORD WINAPI  CBaseCommDevice::ReceiveDataThread(LPVOID pParam)
{
 CBaseCommDevice *pThis=(CBaseCommDevice *)pParam;
 while(pThis->dwStopThread==0&&pThis->m_hComm!=INVALID_HANDLE_VALUE)
 {
 char buf[BUFFLEN];
 memset(buf,0,BUFFLEN);
     int readlen=pThis->ReadData(buf,BUFFLEN);
 if(readlen>0)
 {
 if(strcmp(buf,"~")==0)pThis->OpenDevice();
 else
      pThis->OnRecData(buf,readlen);
 }
 Sleep(100);
 }
 return 0;
}

解决方案 »

  1.   

    ASSERT(m_BaudRate >= 110 || m_BaudRate <= 128000||strlen(m_Port)>0); 好像这assert写的就有点问题。
      

  2.   

    将那一大堆的||,比如
    if( m_osReader.hEvent == NULL || m_osWriter.hEvent == NULL 
        || !SetCommTimeouts(m_hComm, &timeouts) 
        || !BuildCommDCB(lpDef, &dcb) 
        || !SetupComm(m_hComm, m_dwInBuf, m_dwOutBuf)) 
      { 
    写成单独判断的语句,这样可以更清楚的知道什么地方出错了。
      

  3.   

    如果OpenDevice() 返回false,那应该可以跟踪到,我运行的 时候返回应该是true,显示打开端口是成功的,但是接收数据线程里却没取到数据
      

  4.   

    m_hComm = CreateFile(szCom, GENERIC_READ | GENERIC_WRITE, 
                0, NULL, OPEN_EXISTING,0, NULL); 
    问题可能在你设定了缓冲区读N长的时候触发一次读事件,若缓冲区读到的没达到N他就不触发,就不会执行读函数,你可以设置成只要缓冲区有字符来就读