各位大侠:
    小弟现在在写一个串口程序,调试的时候总是出现下面这条错误信息,好像从串口读超过8个字节的时候只能读出8个字节,单步调试的时候好像出错的几率小些,什么原因导致的,是那里没有设置好吗,代码从网上下载的,高手给指点下,小弟不胜感激啊,忙了2天了没有进展,郁闷啊!非常感谢!!!
"Error ReadData(): No EV_RXCHAR occured\n"
主要代码如下:////////////////////////////////////////////////////////////////////////////////////////
// 
//  Function:      Open(LPCSTR lpszPortNum,
//                      DWORD  dwBaudRate, 
//                      BYTE   byParity,
//                      BYTE   byStopBits,
//                      BYTE   byByteSize)
//
//  Return value:  BOOL TRUE or FALSE
//BOOL ComAccess::Open(LPCSTR lpszPortNum, 
                     DWORD  dwBaudRate, 
                     BYTE   byParity,
                     BYTE   byStopBits,
 BYTE   byByteSize)
{
DCB  dcb; // structure that defines the control setting for a serial communications device
BOOL bSuccess;

m_hCom = CreateFile(lpszPortNum,           // pointer to name of the file
                    GENERIC_READ|GENERIC_WRITE, // access mode
                    0,                     // comm devices must be opened w/exclusive-access 
                    NULL,                  // no security attributs 
                    OPEN_EXISTING,         // comm devices must use OPEN_EXISTING 
                    FILE_FLAG_OVERLAPPED,  // overlapped I/O
                    NULL);                 // hTemplate must be NULL for comm devices  if ( m_hCom == INVALID_HANDLE_VALUE ) 
{
// handle the error
ComAccess::ErrorToString("Open(): CreateFile() failed, invalid handle value");

return FALSE;
} //
// Omit the call to SetupComm to use the default queue sizes.
// Get the current configuration.
//
 
bSuccess = GetCommState(m_hCom, &dcb); if ( ! bSuccess ) 
{
// Handle the error.
ComAccess::ErrorToString("Open(): GetCommState() failed");
ComAccess::Close(); return FALSE;
} //
// Fill in the DCB: baud=115200, 8 data bits, no parity, 1 stop bit are default parameters
// dcb.BaudRate = dwBaudRate;
dcb.ByteSize = byByteSize;
dcb.Parity   = byParity;
dcb.StopBits = byStopBits;

bSuccess = SetCommState(m_hCom, &dcb); if ( ! bSuccess ) 
{
// Handle the error. 
ComAccess::ErrorToString("Open(): SetCommState() failed");
ComAccess::Close(); return FALSE;
}
// ++++++added by sunwave
SetupComm(m_hCom, 1024, 1024);
PurgeComm(m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); //清干净输入、输出缓冲区
// ++++++end //printf("open COM1 successful!\n");
return TRUE;
}////////////////////////////////////////////////////////////////////////////////////////
// 
//  Function:      Close(VOID)
//
//  Return value:  VOID
//VOID ComAccess::Close(VOID)
{
if ( m_hCom > 0 )
{
CloseHandle(m_hCom);
} m_hCom = 0; 
}////////////////////////////////////////////////////////////////////////////////////////
// 
//  Function:     WriteData(LPCVOID pdata, 
//                          DWORD   len)
//
//  Return value:  DWORD -1 failed, above, num written bytes
//DWORD ComAccess::WriteData(LPCVOID pdata, 
                           DWORD   len)
{
BOOL  bSuccess;
DWORD written = 0; if ( len < 1 )
return(0);
// ++++++add by sunwave
//FlushFileBuffers(m_hCom);
// ++++++end
// create event for overlapped I/O
m_ov.hEvent = CreateEvent(NULL,   // pointer to security attributes 
                          FALSE,   // flag for manual-reset event 
                          FALSE,  // flag for initial state 
                          "");    // pointer to event-object name  if ( m_ov.hEvent == INVALID_HANDLE_VALUE )
{
// Handle the error.
ComAccess::ErrorToString("WriteData(): CreateEvent() failed");
  
return(-1);
} bSuccess = WriteFile(m_hCom,   // handle to file to write to  
                     pdata,    // pointer to data to write to file 
                     len,      // number of bytes to write 
                     &written, // pointer to number of bytes written 
                     &m_ov);   // pointer to structure needed for overlapped I/O
if ( ComAccess::IsNT() )
{
bSuccess = GetOverlappedResult(m_hCom, &m_ov, &written, TRUE); if ( ! bSuccess )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("WriteData(): GetOverlappedResult() failed"); return(-1);
}
}
else
if ( len != written )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("WriteData(): WriteFile() failed"); return(-1);
} CloseHandle(m_ov.hEvent); return written;
}////////////////////////////////////////////////////////////////////////////////////////
// 
//  Function:      ReadData(LPVOID pdest, 
//                         DWORD  len, 
//                          DWORD  dwMaxWait)
//
//  Return value:  DWORD -1 failed, above, num read bytes
//DWORD ComAccess::ReadData(LPVOID pdest, 
                          DWORD  len, 
                          DWORD  dwMaxWait)
{
BOOL  bSuccess;
DWORD result = 0,
      read   = 0, // num read bytes
      mask   = 0; // a 32-bit variable that receives a mask 
                  // indicating the type of event that occurred if ( len < 1 ) return(0); // ++++++add by sunwave
//FlushFileBuffers(m_hCom);
// ++++++end
// create event for overlapped I/O m_ov.hEvent = CreateEvent(NULL,   // pointer to security attributes 
                          FALSE,   // flag for manual-reset event 
                          FALSE,  // flag for initial state 
                          "");    // pointer to event-object name  if ( m_ov.hEvent == INVALID_HANDLE_VALUE )
{
// Handle the error.
ComAccess::ErrorToString("ReadData(): CreateEvent() failed");
  
return(-1);
} // Specify here the event to be enabled bSuccess = SetCommMask(m_hCom, EV_RXCHAR); if ( ! bSuccess )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("ReadData(): SetCommMask() failed");
  
return(-1);
}
// WaitForSingleObject bSuccess = WaitCommEvent(m_hCom, &mask, &m_ov); if ( ! bSuccess )
{
int err = GetLastError(); if ( err == ERROR_IO_PENDING)
{
result = WaitForSingleObject(m_ov.hEvent, dwMaxWait);  //wait dwMaxWait
                                        // milli seconds before returning
if ( result == WAIT_FAILED )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("ReadData(): WaitForSingleObject() failed");
  
return(-1);
}
}
}

// The specified event occured?

if ( mask & EV_RXCHAR) 
{
bSuccess = ReadFile(m_hCom, // handle of file to read 
                pdest,  // address of buffer that receives data 
            len,    // number of bytes to read 
        &read,  // address of number of bytes read 
    &m_ov); // address of structure for data  if ( ComAccess::IsNT() )
{
bSuccess = GetOverlappedResult(m_hCom, &m_ov, &read, TRUE); if ( ! bSuccess )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("WriteData(): GetOverlappedResult() failed"); return(-1);
}
}
else
if ( ! bSuccess )
{
// Handle the error.
CloseHandle(m_ov.hEvent);
ComAccess::ErrorToString("ReadData(): ReadFile() failed"); return(-1);
}
}
else
{
// Handle the error.
printf("mask = %d\n", mask);
CloseHandle(m_ov.hEvent);
wsprintf(m_lpszErrorMessage, "Error ReadData(): No EV_RXCHAR occured\n"); return(-1);
}

CloseHandle(m_ov.hEvent);

return read;
}

解决方案 »

  1.   

    设置DCB的方法不对,
    应该DCB dcb = {sizeof(DCB)};// 获取其他成员的默认设置
    if( ! GetCommState(m_hCom,&dcb))

      // 失败
    }// 设置相关成员
    dcb.BaudRate = dwBaudRate;
    dcb.ByteSize = byByteSize;
    dcb.Parity   = byParity;
    dcb.StopBits = byStopBits;
      

  2.   

    DCB dcb = {sizeof(DCB)};
    楼上的这句怎么看不太明白,把大小赋给它自己吗?
    但是好像没有出现"Open(): GetCommState() failed"错误信息啊
    显示的是"Error ReadData(): No EV_RXCHAR occured\n"
    周一去试一试,谢谢啊!
      

  3.   

    DCB的第一个成员是
    DWORD DCBlength;
    需要设置为DCB结构的大小.WIN API中很多结构的第一个成员都要设置成其大小,
    这个是MS为了以后扩充结构而定义的.
      

  4.   

    应该是你的commtimeouts结构没有设置而使用默认的原因,在打开串口时用了FILE_FLAG_OVERLAPPED参数,表示以异步方式运行,则readfile函数不一定将缓冲区的数据全部读完才会返回。
      

  5.   

    先谢谢楼上的2位 明天去试一试,楼上的能不能说的再明白点啊,改设置timeouts的值为多少才合适呢,默认是多少?谢谢啊!
      

  6.   

    转帖:(我也从这里受益良多)我收到许多来信,都问我为什么Read函数只读几个字节 ,我都快被问晕了。当然这不是我的库的问题,这是很基本的通讯问题,因为通讯中传输需要时间,当你选择异步模式时你应该注意,这时候Read函数是非阻塞状态,意味着Read函数会迅速扫描缓冲区,把缓冲区里的字节读出来,这时候缓冲区里有多少字节就读多少字节,字节的多少取决于通讯速度与你计算机速度,你通讯越快,读得越多,计算机越快读得越少,这个容易理解吧。所以这个不是一个问题,不需要执著于它,但是你如何实现应用?原文出自http://blog.csdn.net/wujian53/archive/2006/11/23/1409130.aspx
      

  7.   

    好了 也谢谢iicup(双杯献酒)