zcomm.cpp

来自「代码为windows下的无线猫的应用程序(对AT指令的操作)。」· C++ 代码 · 共 734 行 · 第 1/2 页

CPP
734
字号
#include <stdio.h>

#include "stdafx.h"
#include "zcomm.h"

//DWORD FAR PASCAL CommWatchProc( LPSTR lpData );

ZComm::ZComm()
{ 
    fConnected=0;
    fCOMMOpened=0;
    olap=FALSE;
}

ZComm::~ZComm()
{
  
   if (fCOMMOpened==1) {
      fCOMMOpened=0; 
      PurgeComm( idComDev, PURGE_TXABORT | PURGE_RXABORT |
                          PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
      if (olap){
   	     CloseHandle( READ_OS.hEvent ) ;
   		 CloseHandle( WRITE_OS.hEvent ) ;
   	  }
 
	  CloseHandle(idComDev) ;
	  olap=FALSE;
    }

}

ZComm::open(char *szPort,int Baud_rate, BOOL overlapped)
{
    int	retbuflength=0;
   
	
    if (overlapped) { //异步方式打开串口
		memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ;    
        memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ;    

        READ_OS.hEvent = CreateEvent( NULL,    // no security
                                      TRUE,    // explicit reset req
                                     FALSE,   // initial event reset
                                      NULL ) ; // no name
        if (READ_OS.hEvent == NULL)   return  -1  ;
       
        WRITE_OS.hEvent = CreateEvent( NULL,    // no security
                                      TRUE,    // explicit reset req
                                     FALSE,   // initial event reset
                                      NULL ) ; // no name
   	    if (NULL == WRITE_OS.hEvent)
        {
           CloseHandle( READ_OS.hEvent ) ;
           return -1  ;
        }
       
	    idComDev=CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
                  0,                    // exclusive access
                  NULL,                 // no security attrs
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL|
				  FILE_FLAG_OVERLAPPED, // overlapped I/O
                  NULL );
	   
	    olap=TRUE;
	} //同步方式打开串口
	else   idComDev=CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
                  0,                    // exclusive access
                  NULL,                 // no security attrs
                  OPEN_EXISTING,
                  0,  //is overlapped or no
                  NULL );
   
   if (idComDev==(HANDLE) -1){
   	  
	  DWORD RR=GetLastError();
	  CloseHandle(idComDev) ;
      if (olap){
   	     CloseHandle( READ_OS.hEvent ) ;
   		 CloseHandle( WRITE_OS.hEvent ) ;
   	  }
   	  fCOMMOpened=0; 
      olap=FALSE;
   	  return (0);
   }
   
   set_baudrate(Baud_rate);
   fCOMMOpened=1;
   SetupComm(idComDev,11520,2048);
   PurgeComm(idComDev, PURGE_TXABORT | PURGE_RXABORT |
                           PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
   SetCommMask(idComDev, EV_RXFLAG );
   //set time out 
   SetTimeOut(10,50,200);
   return (1);
}

BOOL ZComm::SetTimeOut(DWORD ReadIntervalTimeout,
		               DWORD ReadTotalTimeoutMultiplier,
					   DWORD ReadTotalTimeoutConstant)
{  
   COMMTIMEOUTS timeouts;

   GetCommTimeouts(idComDev,&timeouts);
   timeouts.ReadIntervalTimeout=ReadIntervalTimeout;
   timeouts.ReadTotalTimeoutMultiplier=ReadTotalTimeoutMultiplier;
   timeouts.ReadTotalTimeoutConstant=ReadTotalTimeoutConstant;
   return SetCommTimeouts(idComDev,&timeouts);
}

ZComm::Close()
{
  if (fCOMMOpened==1) {
      fCOMMOpened=0; 
      CloseHandle(idComDev) ;
	  olap=FALSE;
	  if (olap){
   	  CloseHandle( READ_OS.hEvent ) ;
   	  CloseHandle( WRITE_OS.hEvent ) ;
   	  }
	  return 1;
  }
  return 0; 
}

int ZComm::set_baudrate(int baud_rate)
{  
   DCB  dcb;
   BOOL fsuccess;
   
   fsuccess = GetCommState(idComDev, &dcb);
   if (!fsuccess)	return 0;
   
   dcb.BaudRate =baud_rate;
   dcb.ByteSize =8; //number of bits/byte, 4-8 
   dcb.Parity =NOPARITY;
   dcb.StopBits =ONESTOPBIT;
   dcb.EvtChar=0x02;
   /*
   dcb.fOutxCtsFlow = 1;
   dcb.fDtrControl = 1;
   dcb.fRtsControl = 2;
   dcb.EofChar = 0;
   */
   dcb.fOutxCtsFlow = 0;
   dcb.fDtrControl = 0;
   dcb.fRtsControl = 2;
   dcb.EofChar = 26;
   //dcb.fNull=TRUE;

   fsuccess=SetCommState(idComDev, &dcb);
   if (!fsuccess)	return 0;

   return 1;
}

// USE BY READSTREAM()
//
DWORD ZComm::ReadByte(BYTE * buf)
{
      OVERLAPPED  os; 
	  BOOL        fReadStat;
	  DWORD       dwEvtMask;
	  DWORD       dwErrorFlags;
	  COMSTAT     ComStat;
	  DWORD       dwLength;

	  if (fCOMMOpened==0) return 0; //串口未打开

	  if (olap) // OVERLAPPED 
	  { 
         SetCommMask(idComDev, EV_RXCHAR );
		 memset( &os, 0, sizeof( OVERLAPPED ));
		 os.hEvent = CreateEvent( NULL,    // no security
                                  TRUE,    // explicit reset req
                                  FALSE,   // initial event nonsignaled. 
                                  NULL ) ; // no name
         if (os.hEvent == NULL)	 {
            OutputDebugString("\n\r Failed to create event for ReadByte");
	        CloseHandle(os.hEvent);
			return 0;
		 }
		 
		 dwEvtMask = 0 ;
		 WaitCommEvent(idComDev,&dwEvtMask,&os);
 		 
		 if (WaitForSingleObject(os.hEvent,MAXTIMEOUT)==WAIT_TIMEOUT)
		 {
			 OutputDebugString("\n\r time out for ReadByte");
			 CloseHandle(os.hEvent);
			 return 0;
		 } 
		 
		 if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR) 
		 {
			ClearCommError(idComDev, &dwErrorFlags, &ComStat);
	        dwLength = max(1,ComStat.cbInQue);
			//dwLength=1;
		 	fReadStat = ReadFile( idComDev,buf,dwLength,&dwLength, &READ_OS);
		    if (!fReadStat)
			{
		 		OutputDebugString("\n\r can not Read Byte");
		 		CloseHandle(os.hEvent);
				return 0;
            }
			else{
				CloseHandle(os.hEvent);
				return dwLength; 
			}
	 	 }
		 else{
			 CloseHandle(os.hEvent);
			 return 0; 
		 }
	  }
	  else{ //NOT OVERLAPPED
		   dwLength=0; 
	  	   ReadFile(idComDev,buf,1,&dwLength, &READ_OS);
		   return dwLength;
	  }
}

// USE READBYTE()
//
DWORD ZComm::ReadStream(BYTE *buf,int Length)
{
   BYTE temp[1024];
   DWORD ret;
   int i=0;
  
   if (Length<=0) return 0;

   while(i<Length){
	   ret=0;
	   memset(temp,0,1024);
	   ret=ReadByte(temp);
	   //PurgeComm( idComDev,PURGE_RXCLEAR);
	   if (ret==0) 
		   return 0;
       if ((int)(ret+i)>Length)
	   { 
		  memcpy(buf+i,temp,Length);
	   }
	   else memcpy(buf+i,temp,ret);
	   i+=ret;
   }
   return i;
}

// used BY sendcommand()
//
ZComm::Read(BYTE *buf,int nMaxLength)
{
   	BOOL       fReadStat ;
	COMSTAT    ComStat;
	DWORD      dwErrorFlags;
	DWORD      dwLength;
	DWORD      dwError;
	char       szError[ 10 ];
    
	if (fCOMMOpened==0) return 0; //串口未打开

    // only try to read number of bytes in queue 
	ClearCommError(idComDev, &dwErrorFlags, &ComStat) ;
	//dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;
    
	dwLength=nMaxLength;
	if (dwLength > 0)
	{   
		if (olap==TRUE) 
		{
		   fReadStat = ReadFile(idComDev,buf, dwLength, &dwLength,&READ_OS) ;
		   if (!fReadStat)
	 	   {
			   if (GetLastError() == ERROR_IO_PENDING)
			  {
			   	  OutputDebugString("\n\rIO Pending");
			  	  while(!GetOverlappedResult(idComDev, &READ_OS, 
			   		        &dwLength, TRUE ))
			  	  {
			  	  	  dwError = GetLastError();
			   		  if(dwError == ERROR_IO_INCOMPLETE) continue;
			    	  else
			   	 	  {
			   			  // an error occurred, try to recover
			   			  ClearCommError(idComDev,&dwErrorFlags, &ComStat ) ;
			   			  break;
			   		  }
			   	 }
			}
			else // end-----if (GetLastError() == ERROR_IO_PENDING)
			{
			    // some other error occurred
	
			    dwLength = 0 ;
				ClearCommError(idComDev, &dwErrorFlags, &ComStat ) ;
				if (dwErrorFlags >0)
				{
					  wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
					  OutputDebugString(szError);
				}
		    }
		  } // end-----if (!fReadStat) 
		} // end-----if (olap==TRUE) 
		else
		{
		      fReadStat = ReadFile( idComDev,buf, dwLength, &dwLength, NULL ) ;
		      if (!fReadStat)
	 	      {
			  	  dwError = GetLastError();
				  ClearCommError(idComDev,&dwErrorFlags, &ComStat ) ;
				  
				  if (dwErrorFlags >0)
				  {
					 wsprintf( szError, "\n\r <CE-%u>", dwErrorFlags ) ;
					 OutputDebugString(szError);
				  }
			   }
	    }
  
	}
   return  dwLength;
}

int ZComm::ReadString(void* pData, int nLength)
{
	DWORD dwNumRead;    // 串口收到的数据长度
    
    ReadFile(idComDev, pData, (DWORD)nLength, &dwNumRead, NULL);
    
    return (int)dwNumRead;
}

ZComm::Write(BYTE *buf,int buflen)
{
   	BOOL fWriteStat;
	DWORD       dwErrorFlags;
	DWORD   	dwError;
	COMSTAT     ComStat;
	char        szError[ 10 ] ;
    DWORD       ret;

	if (fCOMMOpened==0) return -2 ;//串口未打开
    
    ret=0;
	if (olap) 
	{  
	   fWriteStat = WriteFile(idComDev,buf,buflen,&ret, &WRITE_OS ) ;
	   if (!fWriteStat) 
	   {
	      if ((dwError=GetLastError()) == ERROR_IO_PENDING)
		  {
	    
		   	 while (!GetOverlappedResult(idComDev,&WRITE_OS,&ret, TRUE ))
			 {  
				 dwError = GetLastError();
				 if(dwError == ERROR_IO_INCOMPLETE)
				 {
				     OutputDebugString("write io pending");
					 continue;
				 }
				 else
				 {
				  	 //an error occurred, try to recover
					 wsprintf( szError, "\n\r <CE-%u>", dwError ) ;
					 OutputDebugString(szError);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?