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

📄 commport.cpp

📁 ISP1160 for uCOS-II,使用于lpc2200系列芯片
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        case 56000:
                eBaudrates=EBaud56000;
                break;
        case 57600:
                eBaudrates=EBaud57600;
                break;
        case 115200:
                eBaudrates=EBaud115200;
                break;
        default:
                eBaudrates=EBaud9600;
                return FALSE;
	}
  nTimePerByte=10000/eBaud;
  nTimePerByte+=1;
  return TRUE;
}
//------------------------------------------------------------------
//      串口打开函数
//函数功能:
//         1、打开串口
//         2、调用读写缓冲区设置函数
//         3、调用串口串口忏悔设置函数
//         4、调用超时设置函数
//入口参数:    无
//返回值:成功后,返回值为0。否则返回失败码
//-----------------------------------------------------------------------------
int  CCommPort::OpenPort (int nDataBit,int nStopBit,int nParity)
{
  if (hComm)
        return 102;	//操作串口时,串口已打开
  hComm = ::CreateFile(lpszPort,
		GENERIC_READ|GENERIC_WRITE,
		0,
		0,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
		0);
  if (hComm == INVALID_HANDLE_VALUE){
        hComm = 0;
        return 101;	//不能打开串口
  }

  m_hevtOverlapped = ::CreateEvent(0,true,false,0);
 if (m_hevtOverlapped == 0){
		::CloseHandle(hComm);
		hComm = 0;
		return 200;
  }
  
  
  if (!::SetupComm(hComm,1024*64,1024*64)){
		ClosePort();
		return 205;	//不能设置收发缓冲区
	}
  if(nDataBit<5||nDataBit>8)
        nDataBit=8;

  Setup(eBaudrates ,
        EDataBits(nDataBit),
        EParity(nParity),
        EStopBits(nStopBit)
  );

  SetupReadTimeouts(0);
  return 0;
  
}
//-----------------------------------------------------------------------------
//关闭串口函数
//----------------------------------------------------------------------------
//bR: 是否清DTR、RTS
void  CCommPort::ClosePort (BOOL bR)
{
  if (hComm == 0)
	return ;
  if(bR){
        ClrDTR();
        ClrRTS();
  }

  ::CloseHandle(m_hevtOverlapped);
  m_hevtOverlapped = 0;

  ::CloseHandle(hComm);
  hComm = 0;
}

//-----------------------------------------------------------------------------
//      发送命令函数
//函数功能:发送PC机命令至单片机中,并读取单片机发回的响应信号。
//入口参数:    pOrderBuff - 命令缓冲区指针
//   		pAckBuff - 响应缓冲区指针
//		dwTimeOuts - 等待回应信息时的超时时间
//返回值:成功后,返回值为0; 失败后,返回相应错误码
//-----------------------------------------------------------------------------

 int   CCommPort::SendOrder(BYTE* pOrderBuff,BYTE* pAckBuff,int nTimeOuts)
{
  int nWaitTime=nTimePerByte;           //设置读串口超时系数
  int nAndBgn=nFrameHead & 0xC0;
  int nLen;
  COMSTAT     ComStat;
  DWORD       dwErrorFlags;

  SetupReadTimeouts(20);
  
  //判断此帧长度
  switch(nAndBgn){
        case 0x0: //当命令码长度为1、参数长度为1时
                nLen=3+pOrderBuff[2];
                break;
        case 0x40: //当命令码长度为1、参数长度为2时
                nLen=4+pOrderBuff[2]*256+pOrderBuff[3];
                break;
        case 0x80: //当命令码长度为2、参数长度为1时
                nLen=4+pOrderBuff[3];
                break;
        case 0xC0: //当命令码长度为2、参数长度为2时
                nLen=5+pOrderBuff[3]*256+pOrderBuff[4];
                break;
  }

  
  if (!hComm)
		return 102;	//操作串口时,串口未打开
  
  int CommEro=0;
  Flush();
//发送命令
  CommEro=Write (pOrderBuff,nLen,0,0,nWaitTime*nLen);
  if(CommEro)
        return CommEro;

  //等回应
  ClearCommError(hComm,&dwErrorFlags,&ComStat);
  if(ComStat.cbInQue == 0){
        CommEro=WaitEvent(pAckBuff,nTimeOuts);
  }else{
        int nThreshold=0;
        int CommEro=0;
        BYTE         StartBuff=0x0;
        while(StartBuff!=nFrameHead && nThreshold<3){
             CommEro=Read(&StartBuff,1,0,0,300);
              nThreshold++;
              if(CommEro)
                      return 1;
         }

        pAckBuff [0]=StartBuff;

        BYTE OrdAndLenBuff[4]={0x0};

        int nAndBgn=nFrameHead & 0xC0;
        int nAlreadyRead=0;
        int nFrameLen=0;
  
              //判断接收长度
        switch(nAndBgn){
              case 0x0: //当命令码长度为1、参数长度为1时
                      CommEro=Read(OrdAndLenBuff,2,0,0,nTimeOuts);
                      if(CommEro)
                              return CommEro;
                      pAckBuff[1]=OrdAndLenBuff[0];
                      pAckBuff[2]=OrdAndLenBuff[1];
                      nFrameLen=OrdAndLenBuff[1];
                      nAlreadyRead=3;
                      break;
              case 0x40: //当命令码长度为1、参数长度为2时
                      CommEro=Read(OrdAndLenBuff,3,0,0,nTimeOuts);
                      if(CommEro)
                              return CommEro;
                      pAckBuff[1]=OrdAndLenBuff[0];
                      pAckBuff[2]=OrdAndLenBuff[1];
                      pAckBuff[3]=OrdAndLenBuff[2];
                      nFrameLen=OrdAndLenBuff[1]*256+OrdAndLenBuff[2];
                      nAlreadyRead=4;
                      break;
              case 0x80: //当命令码长度为2、参数长度为1时
                      CommEro=Read(OrdAndLenBuff,3,0,0,nTimeOuts);
                      if(CommEro)
                              return CommEro;
                      pAckBuff[1]=OrdAndLenBuff[0];
                      pAckBuff[2]=OrdAndLenBuff[1];
                      pAckBuff[3]=OrdAndLenBuff[2];
                      nFrameLen=OrdAndLenBuff[1];
                      nAlreadyRead=4;
                      break;
              case 0xC0: //当命令码长度为2、参数长度为2时
                      CommEro=Read(OrdAndLenBuff,4,0,0,nTimeOuts);
                      if(CommEro)
                              return CommEro;
                      pAckBuff[1]=OrdAndLenBuff[0];
                      pAckBuff[2]=OrdAndLenBuff[1];
                      pAckBuff[3]=OrdAndLenBuff[2];
                      pAckBuff[4]=OrdAndLenBuff[3];
                      nFrameLen=OrdAndLenBuff[2]*256+OrdAndLenBuff[3];
                      nAlreadyRead=5;
                      break;
              }


        BYTE *LeaveBuff;
        LeaveBuff=new BYTE[nFrameLen];

        CommEro=Read(LeaveBuff,nFrameLen,0,0,nTimeOuts);
          if(CommEro)
              return CommEro;
        for(int i=0;i<nFrameLen;i++)
              pAckBuff[i+nAlreadyRead]=LeaveBuff[i];
  }
  return CommEro;


}
//---------------------------------------------------------------------------

int CCommPort::SendData(BYTE* pOrderBuff,BYTE* pAckBuff,int nSendLen,int nTimeOuts,
                                        int nRcv,BYTE cEnd,BOOL bIfRcv)
{
  int nWaitTime=nTimePerByte;           //设置读串口超时系数
  if (!hComm)
		return 102;	//操作串口时,串口未打开

  int CommEro=0;
  Flush();
  SetupReadTimeouts(nTimeOuts/nRcv+1);

  //发送命令
  CommEro=Write(pOrderBuff,nSendLen,0,0,nWaitTime*nSendLen);
  if(CommEro)
        return CommEro;

  if(!bIfRcv)
        return 0;
  if(nTimeOuts<=0)
        return 333;     //用户设置参数出错

  if(nRcv>0)
        CommEro=Wait_Cnt(pAckBuff,nTimeOuts,nRcv);
  else
        CommEro=Wait_Byte(pAckBuff,nTimeOuts,cEnd);

  return CommEro;

}
//---------------------------------------------------------------------------
int CCommPort::Wait_Cnt(BYTE* Buff,int nTimeOuts,int nRcvCnt)
{
  int CommEro;
/*
  BYTE byRcv;
  for(int i=0;i<nRcvCnt;i++){
        CommEro=Read(&byRcv,1,0,0,nTimeOuts/nRcvCnt+1);
        if(!CommEro)
                Buff[i]=byRcv;
        else
                break;
 }
*/
  CommEro=Read(Buff,nRcvCnt,0,0,nTimeOuts);
  if(CommEro)
        return CommEro;
  return 0;
}
//----------------------------------------------------------------------------

int CCommPort::Wait_Byte(BYTE* Buff,int nTimeOuts,BYTE cEndByte)
{
  DWORD       dwEvtMask,dwTrans ;
  OVERLAPPED  os ;
  memset( &os, 0, sizeof( OVERLAPPED ) ) ;
  os.hEvent = CreateEvent( NULL,    // no security
		TRUE,    // explicit reset req
		FALSE,   // initial event reset
		NULL ) ; // no name

  if (os.hEvent == NULL)
   	return 1;

  SetMask();
  dwEvtMask=0;
  if(!WaitCommEvent(hComm, &dwEvtMask, &os)){        // 重叠操作

     	if(GetLastError()==ERROR_IO_PENDING){
                // 无限等待重叠操作结果
		// GetOverlappedResult(hComm, &os, &dwTrans, true);
		switch (::WaitForSingleObject(os.hEvent,nTimeOuts)){
			case WAIT_OBJECT_0:
				if (!::GetOverlappedResult(hComm,&os, &dwTrans, TRUE))
					return 209;	//监视串口出错
				break;

			case WAIT_TIMEOUT:
				::CancelIo(hComm);
				return 209;	//监视串口出错

			default:
				return 209;	//监视串口出错
		}
	}else
	   	return 209;	//监视串口出错
  }

  CloseHandle(os.hEvent);
  //清空掩码
  SetCommMask(hComm,0);


  int CommEro=0;
  BYTE  EndBuff=0x0;
  int nCurrentCnt=0;
  int nCurrentWaitTime=nTimeOuts;

  while(EndBuff!=cEndByte){
       CommEro=Read(&EndBuff,1,0,0,nCurrentWaitTime);
       Buff[nCurrentCnt]=EndBuff;
       nCurrentCnt++;
       nCurrentWaitTime=nCurrentWaitTime/nCurrentCnt+100;
       if(CommEro)
		return CommEro;
   }
  return 0;
}
//----------------------------------------------------------------------------
//在缓冲区中读取一数据
int CCommPort::ReadBlock(BYTE* pBuff,int nLen,int nTimeOuts)
{
  SetupReadTimeouts(0);
  COMSTAT     ComStat;
  DWORD       dwErrorFlags;
  ClearCommError(hComm,&dwErrorFlags,&ComStat);

  if(ComStat.cbInQue)
        return(Read(pBuff,nLen,0,0,nTimeOuts));

  DWORD       dwEvtMask,dwTrans ;
  OVERLAPPED  os ;

  memset( &os, 0, sizeof( OVERLAPPED ) ) ;

  os.hEvent = CreateEvent( NULL,    // no security
		TRUE,    // explicit reset req
		FALSE,   // initial event reset
		NULL ) ; // no name

  if (os.hEvent == NULL)
   	return 1;

  SetMask();

  dwEvtMask=0;
  if(!WaitCommEvent(hComm, &dwEvtMask, &os)){        // 重叠操作

     	if(GetLastError()==ERROR_IO_PENDING){
                // 无限等待重叠操作结果
		// GetOverlappedResult(hComm, &os, &dwTrans, true);
		switch (::WaitForSingleObject(os.hEvent,nTimeOuts)){
			case WAIT_OBJECT_0:
				if (!::GetOverlappedResult(hComm,&os, &dwTrans, TRUE))
					return 209;	//监视串口出错
				break;

			case WAIT_TIMEOUT:
				::CancelIo(hComm);
				return 209;	//监视串口出错

			default:
				return 209;	//监视串口出错
		}
	}else
	   	return 209;	//监视串口出错
  }

  CloseHandle(os.hEvent);
    //清空掩码
  SetCommMask(hComm,0);
  return(Read(pBuff,nLen,0,0,nTimeOuts));

}
//----------------------------------------------------------------------------

HANDLE CCommPort::GetCommHandle()
{
  return hComm;
}
//----------------------------------------------------------------------------

BOOL CCommPort::SetDTR()
{
  if (hComm == 0)
        return FALSE;	//操作串口时,串口没打开
  return(EscapeCommFunction(hComm,SETDTR));
}
//----------------------------------------------------------------------------

BOOL CCommPort::ClrDTR()
{
  if (hComm == 0)
        return FALSE;	//操作串口时,串口没打开
  return(EscapeCommFunction(hComm,CLRDTR));

}
//----------------------------------------------------------------------------

BOOL CCommPort::SetRTS()
{
  if (hComm == 0)
        return FALSE;	//操作串口时,串口没打开
  return(EscapeCommFunction(hComm,SETRTS));

}
//----------------------------------------------------------------------------

BOOL CCommPort::ClrRTS()
{
  if (hComm == 0)
        return FALSE;	//操作串口时,串口没打开

  return(EscapeCommFunction(hComm,CLRRTS));

}
//----------------------------------------------------------------------------

int CCommPort::CommWatch(int &nLen,BYTE* pBuff)
{
  DWORD       dwErrorFlags;
  COMSTAT     ComStat;
  ClearCommError(hComm,&dwErrorFlags,&ComStat);
  nLen=ComStat.cbInQue;
  if(nLen>0)
          return(Read(pBuff,nLen,0,0,10*nLen));
  return 0;

}


⌨️ 快捷键说明

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