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

📄 serialport.cpp

📁 串口通信类编程中必不可少的一个类 定义了类函数
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	BOOL bRead = TRUE;
    BOOL bResult =TRUE;
    DWORD dwError =0;
    DWORD BytesRead = 0;
    unsigned char RXBuff = 0;
    //开始无限循环,每次读取一个字节发送至父窗口,直至缓冲区中所有数挚友读取完毕
	for(;;)
		{
			EnterCriticalSection(&port->m_csCommunicationSync);         //进入临界区
			bResult = ClearCommError(port -> m_hComm,&dwError,&comstat);//检测并清除错误条件
            LeaveCriticalSection(&port -> m_csCommunicationSync);
		
			//当缓冲区空时,跳出循环
			if(comstat.cbInQue == 0)
			{
				break;
			}
            //进入临界区
			EnterCriticalSection(&port -> m_csCommunicationSync);
		
			if(bRead)
			{
				//读串口
				bResult = ReadFile(port->m_hComm,   //串口句柄
                                           &RXBuff,    //接收地址
				                           1,         //每次读一字节
                                           &BytesRead,  //返回实际读取的字节数
                                           &port->m_ov); //重叠结构
                //处理错误
				if(!bResult)
                {
					switch(dwError = GetLastError())
					{
					case ERROR_IO_PENDING:
					{
						 //正常返回值,读未完成,调用
						 //GetOverlappedResults()继续下一步
						 bRead = FALSE;
						 break;
                    }
					default:
					{
						//其他错误返回值显示错误信息
						port ->ProcessErrorMessage("ReadFile()");
						break;
					}
					}
				}
			    else
				{
					//读操作已完成,不必再调用 GetOverlappedResults()
					bRead = TRUE;
				}
			}  //close if (bRead)
			if(!bRead)
			{
				bRead = TRUE;
			    //继续完成操作
				bResult = GetOverlappedResult(port->m_hComm,         //串口句柄
												&port->m_ov,    //重叠结构
												&BytesRead,     //实际读取字节数
												TRUE);          //等待标志
					//错误处理
				if(!bResult)
				{
 					port -> ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
				} 
			}//close if (!bRead)
			//离开临界区
			LeaveCriticalSection(&port->m_csCommunicationSync);
			//发送WM_COMM_RXCHAR 消息到父窗口,通知数据到达
					::SendMessage((port->m_pOwner)->m_hWnd,WM_COMM_RXCHAR,(WPARAM)RXBuff,
											 (LPARAM)port ->m_nPortNr);
		}//end forever loop
	}
//ReadBlock采用与ReceiveChar 不同的由用户显式调用的方式读取窗口
BYTE*CSerialPortEx::ReadBlock(CSerialPortEx*port,int&readLen)
{
   COMSTAT comstat;
   BOOL bRead = TRUE;
   BOOL bResult = TRUE;
   DWORD dwError = 0;
   DWORD BytesRead = 0;
   DWORD BytesToRead = readLen;
   BYTE *pRec;
   
   EnterCriticalSection(&port->m_csCommunicationSync);  //进入临界区
   bResult=ClearCommError(port->m_hComm,&dwError,&comstat);//检测并且清除错误重要条件
   LeaveCriticalSection(&port -> m_csCommunicationSync);    //离开临界区
  
   if(comstat.cbInQue ==0)
   {
        //若缓冲区空,则返回NULL
		readLen = 0;
		return NULL;
   }
   else
   {
	   //若缓冲区非空,则为返回数据开辟缓冲区
	   BytesToRead = (BytesToRead +2) >comstat.cbInQue?comstat.cbInQue:BytesToRead+2;
	   pRec = new BYTE[BytesToRead];
   }
   //进入临界区
   EnterCriticalSection(&port->m_csCommunicationSync);
   
   if(bRead)
   {
	   bResult = ReadFile(port ->m_hComm,//串口句柄
		                    pRec,        //接收缓冲区地址
							BytesToRead,  //希望读取的字节数
							&BytesRead,   //实际读取的字节数
							&port->m_ov); //重叠结构
	   //错误处理
	   if(!bResult)
	   {
		   switch(dwError = GetLastError())
		   {
		   case ERROR_IO_PENDING:
			   {
				   //正常返回值,读未完成,调用GetOverlappedResults()继续下一步
				   bRead =FALSE;
				   break;
			   }
		   default:
			   {
				   //其他错误返回值显示错误信息
				   port->ProcessErrorMessage("ReadFile()");
				   break;
			   }
		   }
	   }
	   else
	   {
		//读操作已完成,不必再调用GetOverlappedResults()
		   bRead = TRUE;
	   }
   }//CLOSE if (bRead)
   if(!bRead)
   {
	   bRead = TRUE;
	   //继续完成读操作
	   bResult = GetOverlappedResult(port->m_hComm,//串口句柄
		                             &port->m_ov,  //重叠结构
									 &BytesRead,   //实际读取字节数
									 TRUE);
	   //错误处理
	   if(!bResult)
	   {
		   port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
	   }
   }//close if(!bRead)
   LeaveCriticalSection(&port->m_csCommunicationSync);      //离开临界区

   readLen = BytesRead;              //返回实际读取的字节数
   return pRec;                      //返回所接收数据地址
}
//写串口
void CSerialPortEx::WriteChar(CSerialPortEx*port)
{
	BOOL bWrite= TRUE;
	BOOL bResult = TRUE;
	DWORD BytesSent = 0;

	ResetEvent(port->m_hWriteEvent);    //使该事件回到无信号状态

	//进入临界区
	EnterCriticalSection(&port->m_csCommunicationSync);

	if(bWrite)
	{
		//初始化OVERLAPPED结构
		port->m_ov.Offset=0;
		port->m_ov.InternalHigh = 0;

		//清空缓冲区
		PurgeComm(port->m_hComm,PURGE_RXCHAR|PURGE_TXCLEAR
			                |PURGE_RXABORT|PURGE_TXABORT);
		//写串口
		bResult = WriteFile(port->m_hComm,             //串口句柄
			                  port->m_szWriteBuffer,   //要发送的数据地址
							  port->m_nToSend,         //要发送的数据长度
							  &BytesSent,              //返回实际发送的数据长度
							  &port->m_ov);            //重叠结构
		//错误处理
		if(!bResult)
		{
			DWORD dwError = GetLastError();
			switch(dwError)
			{
			case ERROR_IO_PENDING:
				{
					//正常返回值,写未完成,使用GetOverlappedResults()继续一步
					BytesSent = 0;
					bWrite = FALSE;
					break;
				}
			default:
				{
					//其他错误返回值显示错误信息
					port->ProcessErrorMessage("WriteFile()");
				}
			}
		}
		else
		{
			//若写操作已完成,则离开临界区
			LeaveCriticalSection(&port->m_csCommunicationSync);
		}
	}//end if(bWrite)
	if(!bWrite)
	{
		bWrite=TRUE;
		//继续完成写操作
		bResult = GetOverlappedResult(port->m_hComm,          //串口句柄
			                               &port->m_ov,       //重叠结构
										   &BytesSent,        //已发送字节数
										   TRUE);             //等待标志
		//离开临界区
		LeaveCriticalSection(&port->m_csCommunicationSync);

		//错误处理
		if(!bResult)
		{
			port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
		}
	}//end if(!bWrite)
}
	//将一块内存区中的数据通过串口发送
	void CSerialPortEx::WriteToPort(BYTE*string,int nLength)
	{
		if(m_hComm==0)
		{
			::AfxMessageBox("error strange");
			return;
		}
		//将待发送数据COPY到CSerialPortEx发送缓冲区中
		memset(m_szWriteBuffer,0,m_nWriteBufferSize);
		memcpy(m_szWriteBuffer,string,nLength);
		m_nToSend = nLength;

		//触发写事件
		SetEvent(m_hWriteEvent);
	}
	//将CString类型字符串写入串口
	void CSerialPortEx::WriteToPort(CString str)
	{
		char*buffer=new char[m_nWriteBufferSize];
		memset(buffer,0,m_nWriteBufferSize);
		int nMaxLength=(str.GetLength()+1)>m_nWriteBufferSize?(str.GetLength()+1):m_nWriteBufferSize;
		char *temp=str.GetBuffer(nMaxLength);
		memcpy(buffer,temp,str.GetLength());
		str.ReleaseBuffer();
		WriteToPort((BYTE*)buffer,str.GetLength());
	}
	//获取并显示以指定格式显示错误信息
	void CSerialPortEx::ProcessErrorMessage(char*ErrorText)
	{
		char *Temp = new char[20];

		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;
}
//返回设备控制块
DCB CSerialPortEx::GetDCB()
{
	return m_dcb;
}
//返回串口状态事件
DWORD CSerialPortEx::GetCommEvents()
{
	return m_dwCommEvents;
}
//返回输出缓冲区大小
DWORD CSerialPortEx::GetWriteBufferSize()
{
	return m_nWriteBufferSize;
}



⌨️ 快捷键说明

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