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

📄 serialport.cpp

📁 这是一个完整的无线通讯工程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	TRACE("Thread suspended\n");
	m_Thread->SuspendThread(); 
	return TRUE;	
}


//
// If there is a error, give the right message
//
void CSerialPort::ProcessErrorMessage(char* ErrorText)
{
	return ;
	char *Temp = new char[200];
	
	LPVOID lpMsgBuf;

	FormatMessage( 
		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
		NULL,
		GetLastError(),
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
		(LPTSTR) &lpMsgBuf,
		0,
		NULL 
	);

	sprintf(Temp, "WARNING:  %s Failed with the following error: \n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, m_nPortNr); 
	MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);

	LocalFree(lpMsgBuf);
	delete[] Temp;
}

//
// Write a character.
//
int CSerialPort::WriteCom( BYTE Outbuff[], int size) 
{ 
	HANDLE hComm = m_hComm;
  DWORD nBytesWrite,endtime,lrc; 
  static OVERLAPPED ol; 
  DWORD dwErrorMask,dwError; 
  COMSTAT comstat; 
  ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); 
  ol.Offset=0;        
  ol.OffsetHigh=0; 
  ol.hEvent=NULL;        ///标识事件,数据传送完成时,将它设为信号状态 
  ClearCommError(hComm,&dwErrorMask,&comstat); 
  if(!WriteFile(hComm,Outbuff,size,&nBytesWrite,&ol)) 
  { 
    if((lrc=GetLastError())==ERROR_IO_PENDING) 
    { 
      endtime=GetTickCount()+1000; 
      while(!GetOverlappedResult(hComm,&ol,&nBytesWrite,FALSE)) 
      {  
        dwError=GetLastError(); 
        if(GetTickCount()>endtime) 
        {   
          AfxMessageBox("写串口时间过长,目前串口发送缓冲区中的数据数目为空"); 
          break; 
        } 
        if(dwError=ERROR_IO_INCOMPLETE) 
          continue;     //未完全读完时的正常返回结果 
        else 
        { 
          //  发生错误,尝试恢复! 
          ClearCommError(hComm,&dwError,&comstat); 
		  TRACE("发生错误,尝试恢复! %d\n", dwError);
          break; 
        } 
      } 
    }    
  }   
  FlushFileBuffers(hComm); 
  PurgeComm(hComm,PURGE_TXCLEAR);         
  
  return 1; 
} 

void CSerialPort::WriteChar(CSerialPort* port)
{
	BOOL bWrite = TRUE;
	BOOL bResult = TRUE;

	DWORD BytesSent = 0;

	ResetEvent(port->m_hWriteEvent);

	// Gain ownership of the critical section
	EnterCriticalSection(&port->m_csCommunicationSync);

	if (bWrite)
	{
		// Initailize variables
		port->m_ov.Offset = 0;
		port->m_ov.OffsetHigh = 0;

		// Clear buffer
		PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

		bResult = WriteFile(port->m_hComm,							// Handle to COMM Port
						//	port->m_szWriteBuffer,					// Pointer to message buffer in calling finction
							port->WriteBuf,
							//strlen((char*)port->m_szWriteBuffer),	// Length of message to send
							port->WriteBufLen,
							&BytesSent,								// Where to store the number of bytes sent
							&port->m_ov);							// Overlapped structure

		// deal with any error codes
		if (!bResult)  
		{
			DWORD dwError = GetLastError();
			switch (dwError)
			{
				case ERROR_IO_PENDING:
					{
						// continue to GetOverlappedResults()
						BytesSent = 0;
						bWrite = FALSE;
						break;
					}
				default:
					{
						// all other error codes
						port->ProcessErrorMessage("WriteFile()");
					}
			}
		} 
		else
		{
			LeaveCriticalSection(&port->m_csCommunicationSync);
		}
	} // end if(bWrite)

	if (!bWrite)
	{
		bWrite = TRUE;
	
		bResult = GetOverlappedResult(port->m_hComm,	// Handle to COMM port 
									  &port->m_ov,		// Overlapped structure
									  &BytesSent,		// Stores number of bytes sent
									  TRUE); 			// Wait flag

		LeaveCriticalSection(&port->m_csCommunicationSync);

		// deal with the error code 
		if (!bResult)  
		{
			port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
		}	
	} // end if (!bWrite)

	// Verify that the data size send equals what we tried to send
	//strlen((char*)port->m_szWriteBuffer)
#ifdef _DEBUG
	if (BytesSent != port->WriteBufLen)
	{
		TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, port->WriteBufLen);//strlen((char*)port->m_szWriteBuffer));
	}else{
		//TRACE("(%d)WriteFile[%d]:",bWrite,port->WriteBufLen);
		for(int i = 0 ; i < (int)port->WriteBufLen;i++){
		//	TRACE("%c ",port->WriteBuf[i]);
		}
		//TRACE("\n");
		//TRACE("time = %d\n",GetTickCount()-time1);
		time1 = GetTickCount();
	}
#endif
}

//
// Character received. Inform the owner
//
void CSerialPort::ReceiveChar(CSerialPort* port, COMSTAT comstat)
{
	BOOL  bRead = TRUE; 
	BOOL  bResult = TRUE;
	DWORD dwError = 0;
	DWORD BytesRead = 0;
	unsigned char RXBuff[64];

	for (;;) 
	{ 
		// Gain ownership of the comm port critical section.
		// This process guarantees no other part of this program 
		// is using the port object. 
		
		EnterCriticalSection(&port->m_csCommunicationSync);

		// ClearCommError() will update the COMSTAT structure and
		// clear any other errors.
		
		bResult = ClearCommError(port->m_hComm, &dwError, &comstat);

		LeaveCriticalSection(&port->m_csCommunicationSync);

		// start forever loop.  I use this type of loop because I
		// do not know at runtime how many loops this will have to
		// run. My solution is to start a forever loop and to
		// break out of it when I have processed all of the
		// data available.  Be careful with this approach and
		// be sure your loop will exit.
		// My reasons for this are not as clear in this sample 
		// as it is in my production code, but I have found this 
		// solutiion to be the most efficient way to do this.
		
		if (comstat.cbInQue == 0)
		{
			// break out when all bytes have been read
			//TRACE("comstat.cbInQue == 0\n");
			break;
		}
						
		EnterCriticalSection(&port->m_csCommunicationSync);

		if (bRead)
		{
			bResult = ReadFile(port->m_hComm,		// Handle to COMM port 
							   RXBuff,				// RX Buffer Pointer
							   64,					// Read one byte
							   &BytesRead,			// Stores number of bytes read
							   &port->m_ov);		// pointer to the m_ov structure
			// deal with the error code 
			if (!bResult)  
			{ 
				switch (dwError = GetLastError()) 
				{ 
					case ERROR_IO_PENDING: 	
						{ 
							// asynchronous i/o is still in progress 
							// Proceed on to GetOverlappedResults();
							bRead = FALSE;
							break;
						}
					default:
						{
							// Another error has occured.  Process this error.
							LeaveCriticalSection(&port->m_csCommunicationSync);
							
							port->ProcessErrorMessage("ReadFile()");
							TRACE("during reading com data, a error has occured!\n");
							return ;
							break;
						} 
				}
			}
			else
			{
				// ReadFile() returned complete. It is not necessary to call GetOverlappedResults()
				bRead = TRUE;
			}
		}  // close if (bRead)

		if (!bRead)
		{
			bRead = TRUE;
			bResult = GetOverlappedResult(port->m_hComm,	// Handle to COMM port 
										  &port->m_ov,		// Overlapped structure
										  &BytesRead,		// Stores number of bytes read
										  TRUE); 			// Wait flag

			// deal with the error code 
			if (!bResult)  
			{
				TRACE("getoverlappedresult error\n");
				//port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
			}	
		}  // close if (!bRead)
				
		LeaveCriticalSection(&port->m_csCommunicationSync);

		// notify parent that a byte was received
		::SendMessage((port->m_pOwner)->m_hWnd, WM_COMM_RXCHAR, (WPARAM) RXBuff, (LPARAM) port->m_nPortNr);
		port->InputChar((char)RXBuff);
		
	} // end forever loop
}

void CSerialPort::InputChar(char ch)
{
	EnterCriticalSection(&m_csRecvBufSync);
	if(m_nRecvBuffer < MAX_RECVBUFFER_SIZE-1)
	{
		m_szRecvBuffer[m_nRecvBuffer] = ch;
		m_nRecvBuffer++;
		m_szRecvBuffer[m_nRecvBuffer] = 0;
		//TRACE("%c", ch);
	}
	LeaveCriticalSection(&m_csRecvBufSync);
}
int	CSerialPort::ReadChars(char *szBuf, int nBuf)
{
	EnterCriticalSection(&m_csRecvBufSync);
	int	nRet = nBuf > m_nRecvBuffer ? m_nRecvBuffer : nBuf;
	memcpy( szBuf, m_szRecvBuffer, nRet);
	LeaveCriticalSection(&m_csRecvBufSync);
	return nRet; 
}
int CSerialPort::GetChars(char *szBuf, int nBuf)
{
	EnterCriticalSection(&m_csRecvBufSync);
	int	nRet = nBuf > m_nRecvBuffer ? m_nRecvBuffer : nBuf;
	memcpy( szBuf, m_szRecvBuffer, nRet);
	int	nLost = m_nRecvBuffer - nRet;
	if(nLost == 0)
	{
		ZeroMemory(m_szRecvBuffer, m_nRecvBuffer);
		m_nRecvBuffer = 0;
	}else
	{
		memmove( m_szRecvBuffer, m_szRecvBuffer+nRet, nLost);
		ZeroMemory(m_szRecvBuffer+nLost, nRet);
		m_nRecvBuffer = nLost;
	}
	LeaveCriticalSection(&m_csRecvBufSync);
	return nRet;
}
void CSerialPort::FreeRecvBuf()
{
	EnterCriticalSection(&m_csRecvBufSync);
	ZeroMemory(m_szRecvBuffer, MAX_RECVBUFFER_SIZE);
	m_nRecvBuffer = 0;
	LeaveCriticalSection(&m_csRecvBufSync);
}
void	CSerialPort::SetAsyn(BOOL	bAsyn)
{
	m_bAsyn = bAsyn;
}

//
// Write a string to the port
//
void CSerialPort::WriteToPort(BYTE* string,int strlen)
{		
	if(m_hComm == 0)	return ;
	//assert(m_hComm != 0);

	if(WriteBuf)
		delete WriteBuf;
//	else
		WriteBuf = new BYTE[strlen +1];
	memset(WriteBuf,0,strlen+1);
	memcpy(WriteBuf,string,strlen);
	WriteBufLen = strlen;
	/*
	memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
	strcpy(m_szWriteBuffer, string);
	*/
	// set event for write
	
//	if(m_bAsyn)	//异步
//		SetEvent(m_hWriteEvent);
//	else		//同步
		WriteChar(this);
}

//
// Return the device control block
//
DCB CSerialPort::GetDCB()
{
	return m_dcb;
}

//
// Return the communication event masks
//
DWORD CSerialPort::GetCommEvents()
{
	return m_dwCommEvents;
}

//
// Return the output buffer size
//
DWORD CSerialPort::GetWriteBufferSize()
{
	return m_nWriteBufferSize;
}


BOOL	CSerialPort::SetDCBa(DCB		&dcb)
{
	return SetCommState(m_hComm, &dcb);
}

BOOL  CSerialPort::GetDCBa(DCB     &dcb)
{
  return	GetCommState(m_hComm, &dcb);
}

typedef	struct tagComContext{
	BOOL	bLoop;
	BOOL	bPause;
	WORD	wSleep;
	BYTE	bBuf[128];
	WORD	wLen;
}COMCONTEXT,*LPCOMCONTEXT;

static	LPCOMCONTEXT	*g_CurComContext;

static	BOOL	g_ComContinueSend=FALSE;
static	BYTE	g_sendbuf[128];
static	BYTE	g_bufsize=0;
static	WORD	g_sleep = 10;
static	BOOL	g_pause = FALSE;


UINT	CSerialPort::ComContinueSendThread(LPVOID lpVoid)
{
	CSerialPort	*port = (CSerialPort*)lpVoid;
	int	i = 0;
// 	port->SetAsyn(0);
	
	while(g_ComContinueSend && g_bufsize)
	{
		if(g_pause)	continue;
		if(i == 0 || i == g_sleep)
		{
			i = 0;
			port->WriteToPort(g_sendbuf,g_bufsize);
		}
		if(g_sleep)	Sleep(1);
		if(g_pause)	continue;
		i++;
	}
	g_pause = FALSE;
	g_bufsize = 0;
	return 1;
}

//static	int	stopcnt = 0;
void	CSerialPort::StopSend()
{
	if(g_ComContinueSend==FALSE)	return;
	g_ComContinueSend = FALSE;
	
	while(g_bufsize){
		Sleep(1);
	}
	TRACE("over continue send\n");
	memset(g_sendbuf,0,128);
}
void	CSerialPort::StopContinueSend(BYTE *buf,int size)
{
	TRACE("StopContinueSend\n");
	StopSend();
	if(size)
	WriteToPort(buf,size);
}

void	CSerialPort::StartContinueSend(BYTE *buf,int size,int	sleep)
{
	if(size==0)	return;
	StopSend();
	TRACE("StartContinueSend\n");
	memcpy(g_sendbuf,buf,size);
	g_bufsize = size;
	g_sleep  =	sleep;
	g_ComContinueSend = TRUE;
	AfxBeginThread(ComContinueSendThread,this);
}

//用来修改连发过程中数据包的内容;如:速度;
void CSerialPort::ChgConnectBuf(BYTE *buf, int size)
{
	if(g_ComContinueSend==FALSE)	return;
	if(size <= 0)	return;
	g_pause = TRUE;
	memcpy(g_sendbuf,buf,size);
	g_bufsize = size;
	g_pause = FALSE;
}

⌨️ 快捷键说明

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