串口读的怎么实现编程环境是Visual C++ 2005, 程序中打开PC机的串口,往串口写数据我已经基本解决了。现在是怎么从串口读数据的问题。从论坛上找到的这段代码,包括这个两个函数,如下所示。
请问这个ReadData( void *buffer, int limit   )函数怎么用,是放在一个循环里面不停地查询吗? 另外这个ReadDataWaiting( void )函数怎么用?
谢谢!//////////////////////////////////////////////////////////////
int CSerialYB::ReadDataWaiting( void ) 
{  if( !m_bOpened || m_hIDComDev == NULL )   return( 0 );  DWORD dwErrorFlags; 
COMSTAT ComStat;  ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );  return(   (int)ComStat.cbInQue   ); 
} /////////////////////////////////////////////////////////////////////////
int CSerialYB::ReadData( void *buffer,  
 int limit   ) 

if( !m_bOpened || m_hIDComDev == NULL )   
return( 0 );  BOOL  bReadStatus; 
DWORD dwBytesRead, dwErrorFlags; 
COMSTAT ComStat;  ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );  if( !ComStat.cbInQue )   
return( 0 ); 
dwBytesRead = (DWORD)ComStat.cbInQue;  if( limit < (int)dwBytesRead )   
dwBytesRead = (DWORD)limit; 
bReadStatus = ReadFile( 
            m_hIDComDev,
buffer, 
dwBytesRead, 
&dwBytesRead, 
&m_OverlappedRead   );  if( !bReadStatus )

if( GetLastError() == ERROR_IO_PENDING )

WaitForSingleObject( m_OverlappedRead.hEvent, 2000 ); 
return( (int)dwBytesRead ); 

return(   0   ); 
}  return(   (int)   dwBytesRead   ); 

解决方案 »

  1.   

    谢谢楼上的学长,读之前先OpenFile这个我明白,肯定要这么做的,我不明白的地方是如何用这个读的函数,是在一个for循环里不停的读吗?那样是不是很费时间!
      

  2.   


    char rdMessage [100];
    if (Serial.ReadDataWaiting()) 
    {
        Serial.ReadData(rdMessage,100);
        .........
        .........
    }
      

  3.   

    应该是这样的:因为你的程序中是异步执行读串口,所以会立即返回,如果还有数据没有读完的话,会返回一个表示此状态的值,具体可以查msdn,然后应该再不停的继续读,直到读完并返回一个成功的标志,以结束本次的一个完整的读操作。
    具体到当串口上有数据时,我记得好像可以通过通知的方式告知程序,就像socket一样。
      

  4.   


    DWORD CCom::ThreadProc()
    {
    if(!::SetCommMask(m_hCom, m_dwMaskEvent))
    {
    ::MessageBox(m_hNotifyWnd, " SetCommMask failed", "", 0);
    return -1;
    }

    DWORD dwError, dwMask, dwTrans;
    COMSTAT Stat;

    while(!m_bExit)
    {
    dwMask = 0;
    if(!::WaitCommEvent(m_hCom, &dwMask, &m_WaitOl))
    {
    if(::GetLastError() == ERROR_IO_PENDING)
    {
    ::GetOverlappedResult(m_hCom, &m_WaitOl, &dwTrans, TRUE);
    }
    else
    continue;
    }

    switch(dwMask)
    {
    case EV_RXCHAR:
    {
    // 有数据进来,获取数据大小
    ::ClearCommError(m_hCom, &dwError, &Stat);
    if(Stat.cbInQue >= m_dwNotifyNum)
    {
    OnReceive();
    }
    }
    break;

    case EV_TXEMPTY: // 输出缓冲区中的最后一个字符被发送了
    OnTXEmpty();
    break;
    case EV_CTS: // clear-to-send信号改变
    OnCTS();
    break;

    case EV_DSR: // data-set-ready信号改变
    OnDSR();
    break;

    case EV_RING:
    OnRing();
    break;

    case EV_RLSD:
    OnRLSD();
    break;

    case EV_BREAK:
    OnBreak();
    break;

    case EV_ERR:
    OnError();
    break;
    default:
    continue;
    }
    }
    return 0;
    }
      

  5.   

    顶楼上,通常读串口就是这两种方式,如果是在调试阶段,为了实现方便,通常是采用死循环的方式来不停的读串口,但真正实现以后,应改为IO消息驱动的方式,就类似MSCOMM控件的,只有在收到数据时才会触发相应事件进行读取。具体的API我记得好象要用到回调函数和DeviceIoControl