⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 comport.cpp

📁 gps对时
💻 CPP
字号:
// ComPort.cpp: implementation of the CComPort class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "RegionComm.h"
#include "ComPort.h"
#include "Communication.h"
#include "RegionSocket.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

extern bool bgpsOK;
extern long igps;
extern CString sgps;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CComPort::CComPort(CCommunication *pComm)
{
    m_bPortOpen=FALSE;
	m_ComPort=0;
	m_ComBitRate=9600;    
	m_pOwner = pComm;
	TimeOutCount=15;
	IsConnected=FALSE;
	nTimeCount=-1;
}

CComPort::~CComPort()
{
	SetCommMask( m_hcom, 0 ) ;
    if (m_hcom != INVALID_HANDLE_VALUE)
		::CloseHandle(m_hcom);
    ::CloseHandle(m_hProcessEvent);
    CloseHandle(m_osRead.hEvent );
    CloseHandle(m_osWrite.hEvent );
    CloseHandle(m_osWait.hEvent);
	//Close();
}
//打开串口
BOOL CComPort::Open()
{	
   //   COMMTIMEOUTS  CommTimeOuts ;
   CString portstr;   
   DCB        dcb ;
   
    memset(&m_osRead, 0, sizeof(OVERLAPPED));
	if( NULL==(m_osRead.hEvent = CreateEvent( NULL,    // no security
                                TRUE,    // explicit reset req
                                FALSE,   // initial event reset
                                NULL ) )) // no name
	       return(FALSE);
   memset(&m_osWrite, 0, sizeof(OVERLAPPED));
   if( NULL==(m_osWrite.hEvent = CreateEvent( NULL,    // no security
                                 TRUE,    // explicit reset req
                                 FALSE,   // initial event reset
                                 NULL )))   //no name
			return(FALSE);
   
   memset(&m_osWait, 0, sizeof(OVERLAPPED));
   if(NULL==(m_osWait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
	        return(FALSE);
   if(NULL==(m_hProcessEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL)))
	        return(FALSE);

   if(m_ComPort==0)
	   return(FALSE);
   if(m_bPortOpen)
   {
	   m_bPortOpen=FALSE;
	   CloseHandle(m_hcom);
   }
   portstr.Format("\\\\.\\Com%d",m_ComPort); 

   if ((m_hcom=CreateFile( portstr, GENERIC_READ|GENERIC_WRITE,
                  0,                    // exclusive access
                  NULL,                 // no security attrs
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL |
                  FILE_FLAG_OVERLAPPED, // overlapped I/O   
                  NULL )) == (HANDLE) -1 )
   {	 
      return ( FALSE ) ;
   }

  // setup device buffers
  SetupComm( m_hcom, 4096, 4096 ) ;
  
   dcb.DCBlength = sizeof( DCB ) ;
   GetCommState( m_hcom, &dcb );
	   
   dcb.BaudRate =m_ComBitRate;
   dcb.ByteSize =8 ;
   dcb.Parity = NOPARITY ;
   dcb.StopBits = ONESTOPBIT ;

   // setup hardware flow control
   dcb.fOutxDsrFlow =FALSE ;
   dcb.fDtrControl = DTR_CONTROL_ENABLE ;

   dcb.fOutxCtsFlow = FALSE ;
   dcb.fRtsControl = RTS_CONTROL_ENABLE ;
   // setup software flow control
   // other various settings
   dcb.fBinary = TRUE ;
  // dcb.fParity = FALSE ;
   if(!SetCommState(m_hcom, &dcb ) )
   {	   
	   return(FALSE);
   }
   //SetCommMask(m_hComm, EV_RXCHAR);
   m_bPortOpen=TRUE;
   if(!SetCommMask( m_hcom, EV_RXCHAR ))
	   return(FALSE);
   else
       return(TRUE);  
}
//关闭串口
void CComPort::Close()
{
   if(!m_bPortOpen)
	   return;
   if (m_hcom != INVALID_HANDLE_VALUE)
		::CloseHandle(m_hcom);
   m_bPortOpen=FALSE;
   
}
//读串口
int CComPort::ReadComm(BYTE* MyBuff, int rCount)
{
   BOOL       fReadStat ;
   COMSTAT    ComStat ;
   DWORD      dwErrorFlags;
   DWORD      dwLength;
   DWORD      dwError;

   
   // only try to read number of bytes in queue
   ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;
   dwLength = min( (DWORD)rCount, ComStat.cbInQue ) ;
   if (dwLength > 0)
   {
      fReadStat = ReadFile( m_hcom, MyBuff,
		                    dwLength, &dwLength, &m_osRead ) ;
      if (!fReadStat)
      {
          dwError = GetLastError();
		  if (GetLastError() == ERROR_IO_PENDING)
         {            
            // We have to wait for read to complete.
             // This function will timeout according to the
            // CommTimeOuts.ReadTotalTimeoutConstant variable
            // Every time it times out, check for port errors
            while(!GetOverlappedResult( m_hcom ,
               &m_osRead, &dwLength, TRUE ))
            {
               dwError = GetLastError();
               if(dwError == ERROR_IO_INCOMPLETE)
                  // normal result if not finished
                  continue;
               else
               {
                  // an error occurred, try to recover
                  ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;       
               }
            }

	      }
         else
         {
            // some other error occurred
            dwLength = 0 ;
            ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;       
         }
      }
   }
   return ( dwLength ) ;
}
//写串口
BOOL CComPort::WriteComm(BYTE * MyBuff, int wCount)
{
	 BOOL        fWriteStat ;
   DWORD       dwBytesWritten ;   
   DWORD       dwErrorFlags;
   DWORD   	   dwError;
   DWORD       dwBytesSent=0;
   COMSTAT     ComStat;

   fWriteStat = WriteFile( m_hcom, MyBuff, wCount,
                           &dwBytesWritten, &m_osWrite ) ;
   if (!fWriteStat)
   {
      if(GetLastError() == ERROR_IO_PENDING)
      {
         while(!GetOverlappedResult( m_hcom,
            &m_osWrite, &dwBytesWritten, TRUE ))
         {
            dwError = GetLastError();
            if(dwError == ERROR_IO_INCOMPLETE)
            {
               // normal result if not finished
               dwBytesSent += dwBytesWritten;
               continue;
            }
            else
            {             
               ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;              
               break;
            }
         }
         dwBytesSent += dwBytesWritten;
      }
      else
      {
         // some other error occurred
         ClearCommError( m_hcom, &dwErrorFlags, &ComStat ) ;         
         return ( FALSE );
      }
   }
   return ( TRUE ) ;

}
//从串口读数据
void CComPort::ReadComData()
{
//     BYTE TmpBuffReadData[m_MaxTableLen];
	 int  datLength;

	 if(!m_bPortOpen)
		 return;
	 datLength=ReadComm(TmpBuffReadData,m_MaxTableLen); 
	 while(datLength>0)
	 {   		 
		 MyComBuff.SaveBuff(TmpBuffReadData,datLength);
		 datLength=ReadComm(TmpBuffReadData,m_MaxTableLen); 
	}
    ::SetEvent(m_hProcessEvent);
	 return;
}
//外部线程只需要调用GetTable()即可完成通信端口表格的处理
//GetTable()把不需要转发的通信协议表格自己自动处理
//需要转发的表格通过pRegionSocket指针转发出去
//具体的通信协议语义的处理由该过程负责
BOOL CComPort::ProcessTable()
{
//	 BYTE  rBuff[m_MaxTableLen];
//	 int  rCount;
	 COleDateTime tgps;
     while (MyComBuff.GetTab(&tgps))
	 {
		 igps=0;

		 COleDateTimeSpan tspan;
		 COleDateTime  pTime;	
		 pTime = COleDateTime::GetCurrentTime();
		 tspan=pTime-tgps;
		 //误差10分钟才对时
//		TRACE("%d-%d-%d %d:%d:%d \n ",tgps.GetYear(),tgps.GetMonth(),tgps.GetDay(),tgps.GetHour(),tgps.GetMinute(),tgps.GetSecond());
		 double dl;
		 dl=tspan.GetTotalSeconds();
		 if(dl!= 0 && dl>-600 && dl<600) 
		 {
			SYSTEMTIME st; 
			st.wYear = tgps.GetYear();
			st.wMonth = tgps.GetMonth();
			st.wDay = tgps.GetDay();
			st.wHour = tgps.GetHour();
			st.wMinute = tgps.GetMinute();
			st.wSecond = tgps.GetSecond();
			st.wMilliseconds = 0;
			st.wDayOfWeek = 0;
			SetLocalTime(&st);
			sgps.Format("对时前%s 对时后%s",pTime.Format("%H:%M:%S"),tgps.Format("%H:%M:%S"));
		 }
	 }
	 return(TRUE);
}
//把未打包的表格打包后发送
BOOL CComPort::SendTable(BYTE *tabBuff, int tabCount)
{
	//lv test 060808
	long ltime,ltime2;
	ltime=GetTickCount();

//     BYTE TmpBuff[m_MaxTableLen];
	 int i,packLength;

	 if(!m_bPortOpen)
		 return(FALSE);
	 if(tabCount>m_MaxTableLen)//253)
		 return(FALSE);
	 for(i=0;i<tabCount;i++)
		 TmpBuff[i]=tabBuff[i];
	 if( (packLength=MyComBuff.PackTable(TmpBuff,tabCount))>0)
     {
		 WriteComm(TmpBuff,packLength);		
		 
		 //lv test 060808
		 ltime2=GetTickCount();
		 ltime=ltime2-ltime;
		 if(ltime>10)
			 TRACE("CComPort::SendTable time %dms",ltime);

		 return(TRUE);
	 }
	 else
	 {
		 TRACE("CComPort::SendTable FALSE");
		 return(FALSE);
	 }
}

//给某个设备转发未打包的数据表格。处理:首先查找本端口是否包含该设备,然后打包,再发送
BOOL CComPort::TransmitTable( BYTE tDeviceNo, BYTE *sBuff, int sCount)
{    
	sBuff[5]=0;
	sBuff[6]=tDeviceNo;
	if(m_pOwner->m_pServerSocket->m_bAskConnect)
		m_pOwner->m_pServerSocket->SendTable(sBuff,sCount); 

 	return TRUE;
}
//发送应答请求连接
void CComPort::SendAck(BYTE sDeviceType,BYTE sDeviceNo)
{
     BYTE sBuff[7];
     sBuff[0]=0;
	 sBuff[1]=7;
	 sBuff[2]=RegionNo;
	 sBuff[3]=MainLinkCode;
	 sBuff[4]=AckCnt;
	 sBuff[5]=sDeviceType;
	 sBuff[6]=sDeviceNo;
	 SendTable(sBuff,7);
}
//发送查询请求连接
void CComPort::SendAckQry(BYTE sDeviceType,BYTE sDeviceNo)
{
     BYTE sBuff[7];
     sBuff[0]=0;
	 sBuff[1]=7;
	 sBuff[2]=RegionNo;
	 sBuff[3]=MainLinkCode;
	 sBuff[4]=AckQry;
	 sBuff[5]=sDeviceType;
	 sBuff[6]=sDeviceNo;
	 SendTable(sBuff,7);
}
//应答请求连接处理
void CComPort::AskCntProc(BYTE sDeviceType, BYTE sDeviceNo)
{
	SendAck(sDeviceType,sDeviceNo);

	if(!IsConnected)
	{
		BYTE  b=1;
		NotifyStatus(TRUE);//向中心发送
		DWORD  lParam= (LPARAM)MAKELONG(
			    MAKEWORD(m_ComPort,sDeviceNo),
				MAKEWORD(b,0));
		nTimeCount=0;
		AfxGetMainWnd()->PostMessage(WM_COMMAND, IDM_LINKDEVUPDATE,lParam);			
        IsConnected=TRUE;		
	}	
}
//应答查询连接
void CComPort::QryCmdProc(BYTE sDeviceType, BYTE sDeviceNo)
{
	if(!IsConnected)
		return;	
	 nTimeCount=0;	
	 SendAckQry(sDeviceType,sDeviceNo);
	
}


//waits for an event to occur for a specified communications device
void CComPort::WaitCommEvent()
{
	ASSERT(m_osWait.hEvent != NULL);
	ASSERT(m_hcom != INVALID_HANDLE_VALUE);

	if (m_bPortOpen) 	
	{
		BOOL bRet = ::WaitCommEvent(m_hcom, &m_dwEventMask, &m_osWait);		
		if(!bRet)
		{
			long ErrNo=::GetLastError(); 
		}
	}
}

//向中心发送设备状态信息
void CComPort::NotifyStatus(BOOL iConnected)
{
	if(m_pOwner->m_pServerSocket==NULL)
		 return;
	 if(!m_pOwner->m_pServerSocket->m_IsConnected )
		 return;	
	m_pOwner->m_pServerSocket->NotifyLineStatusTab(0,m_DeviceNo,iConnected);
}
//设置参数
void CComPort::SetPamera(BYTE Port, long BitRate,BYTE DeviceType,BYTE DeviceNo,CString Depict)
{
	m_ComPort = Port;
	m_ComBitRate = BitRate;
	m_DeviceType= DeviceType;
	m_DeviceNo =DeviceNo;
	m_Depict = Depict;
}

void CComPort::AdjustDevConnect()
{	    
		if(IsConnected)
		{		
			nTimeCount++;
			if(nTimeCount>TimeOutCount)
			{			
				IsConnected = FALSE;
				nTimeCount=-1;
				NotifyStatus(FALSE);//设备的连接状态发生变化时向中心发送通知表格
				DWORD  lParam= (LPARAM)MAKELONG(
			    MAKEWORD(m_ComPort,m_DeviceNo),
				MAKEWORD(0,0));		
		        AfxGetMainWnd()->PostMessage(WM_COMMAND, IDM_LINKDEVUPDATE,lParam);							
			}
		}
}

int CComPort::GetMyDeviceNo()
{
  return(m_DeviceNo);
}

void CComPort::SendSelfControl()
{
	 BYTE sBuff[11];
     sBuff[0]=0;
	 sBuff[1]=11;
	 sBuff[2]=RegionNo;
	 sBuff[3]=MainLinkCode;
	 sBuff[4]=ModeStageCmd;
	 sBuff[5]=m_DeviceType;
	 sBuff[6]=m_DeviceNo;
	 sBuff[7]=SelfControl;
	 sBuff[8]=0;
	 SendTable(sBuff,11);
}

⌨️ 快捷键说明

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