登录
首页 串口通信 串口通信
回帖 发帖
正文

主题:WINDOWS下的异步串行通讯

点击:10730 回复:5

各位同行好:
   本人初入该网站,对该站的一些话题很感兴趣,对于WINDOWS的串行通讯,我认为采用异步
方式可能会更好,下面是一段用vc++ 写的通讯程序,本人曾用在多个项目中,供大家参考。
 
/////////////
CComm::CComm()
{
}
CComm::~CComm()
{
}
void CComm::SetCommByteSize(BYTE bByteSize)
{
m_bByteSize=bByteSize;
}
void CComm::SetCommParity(BYTE bParity)
{
m_bParity=bParity;
}
void CComm::SetCommStopBits(BYTE bStopBit)
{
m_bStopBits=bStopBit;
}
BOOL CComm::OpenCommConnect(COMMINFO commInfo)
{
  if(m_osRead.hEvent==NULL){return FALSE;}
  COMMTIMEOUTS  CommTimeOuts ;
  char szPort[15],szTemp[64];
  wsprintf(szPort,"COM%d",commInfo.bPort);
  m_idComDev=CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
                 0,                    
                 NULL,                
                 OPEN_EXISTING,
                 FILE_ATTRIBUTE_NORMAL |
                 FILE_FLAG_OVERLAPPED,
                 NULL );
  if(!m_idComDev )
  {
  wsprintf(szTemp,"Open %s Fail",szPort);
  MessageBox(NULL,szTemp,"Ininital Com Error",MB_OK);
  return FALSE;
  }
  if(SetupCommConnect(commInfo))
  {
m_fConnected=true;
  CommTimeOuts.ReadIntervalTimeout = 0;
   CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
   CommTimeOuts.ReadTotalTimeoutConstant = 200;
   CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant =50 ;
   SetCommTimeouts( m_idComDev, &CommTimeOuts ) ;
SetupComm(m_idComDev,256,256);// set the len of buffer for tansfer
PurgeComm(m_idComDev,PURGE_TXABORT | PURGE_RXABORT |
                        PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
EscapeCommFunction( m_idComDev, SETDTR ) ;
return TRUE;
  }
  else
  {
m_fConnected=false;
CloseHandle(m_idComDev);
return FALSE;
}
}
BOOL CComm::SetupCommConnect(COMMINFO commInfo)
{
  BOOL       fRetVal ;
  DCB        dcb ;
  dcb.DCBlength = sizeof( DCB ) ;
  GetCommState(m_idComDev, &dcb ) ;
  dcb.BaudRate = commInfo.dwBaudRate;
  dcb.ByteSize = commInfo.bByteSize;
  dcb.Parity =commInfo.bParity;
  dcb.StopBits =commInfo.bStopBits ;
  fRetVal = SetCommState(m_idComDev,&dcb) ;
  return ( fRetVal ) ;
}
BOOL CComm::CloseConnect()
{
if(!m_fConnected)
return TRUE;
m_fConnected=false;
SetCommMask( m_idComDev, 0 ) ;
   PurgeComm( m_idComDev , PURGE_TXABORT | PURGE_RXABORT |
                          PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
   EscapeCommFunction(m_idComDev, CLRDTR ) ;
   CloseHandle(m_osRead.hEvent);
   CloseHandle(m_osWrite.hEvent);
   CloseHandle( m_idComDev ) ;
   return TRUE;
}
int CComm::ReadFromComm(unsigned char* lpszRcvBuffer,int iMaxLen,DWORD& error )
{
  DWORD      dwLengthrd;
  DWORD      dwLength;
  if(m_idComDev==(HANDLE)-1)
    return 0;
   dwLength =iMaxLen;
   if(!waitonread)
{
if(!ReadFile( m_idComDev, lpszRcvBuffer, dwLength, &dwLengthrd, &m_osRead))
{  
  if (GetLastError() != ERROR_IO_PENDING)
{ Sleep(1000);
 error=1;
return 0;}
  waitonread=true;
}
else
{   error=0;
return dwLengthrd;}
}
  if(waitonread)
  {  
 if(WaitForSingleObject(m_osRead.hEvent,500)!=WAIT_OBJECT_0)
     {   error=3;
 return 0;}
    if(!GetOverlappedResult( m_idComDev,&m_osRead, &dwLengthrd, FALSE ))
{
      return 0;

}
    waitonread=false;
  }
  error=0;
  return ( dwLengthrd ) ;
}
int CComm::WriteToComm(char* lpszSendBuffer,DWORD  dwLength,DWORD& error)
{
  DWORD       dwBytesWritten ;
 
   
  if(m_idComDev==(HANDLE)-1)
    return 0;
   if(!waitonwrite)
{
if(!WriteFile( m_idComDev, lpszSendBuffer, dwLength, &dwBytesWritten, &m_osWrite))
{  
  if (GetLastError() != ERROR_IO_PENDING)
  {
error=1;
Sleep(1000);
return 0;
}
  waitonwrite=true;
}
else
{   error=0;
return dwBytesWritten;}
}
  if(waitonwrite)
  {  
 if(WaitForSingleObject(m_osWrite.hEvent,500)!=WAIT_OBJECT_0)
     {   error=2 ;
 return 0;}
    if(!GetOverlappedResult( m_idComDev,&m_osWrite, &dwBytesWritten, FALSE ))
{
    return 0;
}
  waitonwrite=false;
  }
   error=0;
  return (dwBytesWritten ) ;
}
HANDLE CComm::GetComDev()
{
return m_idComDev;
}
BOOL CComm::GetConnected()
{
return m_fConnected;
}
void CComm::SetBaudRate(DWORD dwBaudRate)
{
m_dwBaudRate=dwBaudRate;
}
void CComm::SetCommPort(BYTE bPort)
{
m_bPort=bPort;
}
BOOL CComm::ChangeBaudRate(DWORD dwBaudRate)
{
  BOOL       fRetVal;
  DCB        dcb;
  dcb.DCBlength = sizeof( DCB ) ;
  GetCommState(m_idComDev, &dcb ) ;
  m_dwBaudRate=dwBaudRate;
  dcb.BaudRate = m_dwBaudRate;
  fRetVal = SetCommState(m_idComDev,&dcb) ;
  return ( fRetVal ) ;
}
BOOL CComm::ChangeCommByteSize(BYTE bByteSize)
{
   BOOL       fRetVal;
   DCB        dcb;
   dcb.DCBlength = sizeof( DCB ) ;
   GetCommState(m_idComDev, &dcb ) ;
   m_bByteSize=bByteSize;
dcb.ByteSize = m_bByteSize;  
fRetVal = SetCommState(m_idComDev,&dcb) ;
   return ( fRetVal );
}
BOOL CComm::ChangeCommParity(BYTE bParity)
{
BOOL       fRetVal;
   DCB        dcb;
   dcb.DCBlength = sizeof( DCB ) ;
   GetCommState(m_idComDev, &dcb ) ;
   m_bParity=bParity;
dcb.Parity = m_bParity;
  fRetVal = SetCommState(m_idComDev,&dcb) ;
   return ( fRetVal );
}
BOOL CComm::ChangeCommStopBits(BYTE bStopBit)
{
BOOL       fRetVal;
   DCB        dcb;
   dcb.DCBlength = sizeof( DCB ) ;
   GetCommState(m_idComDev, &dcb ) ;
   m_bStopBits=bStopBit;
dcb.StopBits = m_bStopBits;
fRetVal = SetCommState(m_idComDev,&dcb) ;
   return ( fRetVal );
}
void CComm::purge()
{
PurgeComm(m_idComDev,PURGE_RXCLEAR|PURGE_TXCLEAR);
}
void CComm::InitParam()
{
m_fConnected=false;
}
02-04-12 00:05
void XhComm::InitCom()
{
m_idComDev=0;
m_fConnected=false;
   memset( &m_osWrite, 0, sizeof( OVERLAPPED ) ) ;
memset( &m_osRead, 0, sizeof( OVERLAPPED ) ) ;
waitonread=false;
   waitonwrite=false;
m_osRead.hEvent=CreateEvent(NULL,TRUE, FALSE,NULL);
m_osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(m_osWrite.hEvent==NULL) {CloseHandle(m_osRead.hEvent);}
}
02-04-12 00:15
ok,请问用vb怎么写?
03-01-13 16:32
ok! 但是我只会VB
05-10-10 10:22
485通信编程的难点在于完整正确的数据包的提取,一般有二种方法:
  1: 数据包前加同步帧,包长度信息,校验码.
  2: 通过接收数据的时间判断,如>50ms未有新数据,判断一个包接收结束. 欢迎到我网站下载 www.tiasky.com
  串口调试工具:SPCfgTest.zip 大小为 252 KB
   调整字节串接收时间(10mS~200mS),可将一般串口调试工具收不全的数据全收全;或不应断开收的数据收全、收完整。
05-10-16 08:28
学习一下。。。
13-11-25 16:32

工控新闻

更多新闻资讯