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

📄 serialport.cpp

📁 本程序是一个宾馆程控电话系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
	TRACE("Thread suspended\n");
	m_Thread->SuspendThread(); 
	return TRUE;	
}


//
//	获取并显示以指定格式显示错误信息
//
void CSerialPort::ProcessErrorMessage(char* ErrorText)
{
	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;
}

//
//	向串口写一个字符
//
void CSerialPort::WriteChar(CSerialPort* 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.OffsetHigh = 0;
		
		//	清空缓冲区
		PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
		
		//	写串口
		bResult = WriteFile(port->m_hComm,							// 串口句柄
			port->m_szWriteBuffer,					// 要发送的数据地址
			strlen((char*)port->m_szWriteBuffer),	// 要发送的数据长度
			&BytesSent,								// 返回实际发送的数据长度
			&port->m_ov);							// Overlapped 重叠结构
		
		
		//	错误处理
		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,		// Overlapped 重叠结构
			&BytesSent,		// 以发送字节数
			TRUE); 			// 等待标志
		
		//清空临界区
		LeaveCriticalSection(&port->m_csCommunicationSync);
		
		
		//	处理错误
		if (!bResult)  
		{
			port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
		}	
	} // end if (!bWrite)
	
	// Verify that the data size send equals what we tried to send
	//	检验发出的数据大小是否等于我们要发的数据大小
	if (BytesSent != strlen((char*)port->m_szWriteBuffer))
	{
		TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)port->m_szWriteBuffer));
	}
}

//
//	收到字符,通知所有者
//	ReceiveChar不需用户调用,串口主线程在有数据到达串口时自动调用改函数,
//	它将读取到的数据通过自定义消息WM_COMM_RXCHAR发送给父窗口m_pOwner,
//	调用着只需在该窗口内处理WM_COMM_RXCHAR消息即可.
//
void CSerialPort::ReceiveChar(CSerialPort* port, COMSTAT comstat)
{
	BOOL  bRead = TRUE; 
	BOOL  bResult = TRUE;
	DWORD dwError = 0;
	DWORD BytesRead = 0;
	unsigned char RXBuff;
	
	//开始无限循环,每次读取一个字节发送至父窗口,直至缓冲区中所有数据读取完毕
	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,		// Overlapped 重叠结构
				&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结束无限循环
	
}

//
//	向串口写一个字符串,主要用途是把Edit中的内容发送出去
//
void CSerialPort::WriteToPort(char* string)
{		
	assert(m_hComm != 0);	//	当结果有错误时,输出此错误的诊断信息
	
	//	将待发送数据复制到CSerialPort 发送缓冲区中
	memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
	strcpy(m_szWriteBuffer, string);	//	拷贝字符串
	
	//	触发写事件
	SetEvent(m_hWriteEvent);
}

//
//	返回设备控制块
//
DCB CSerialPort::GetDCB()
{
	return m_dcb;
}

//
//	返回串口状态事件
//
DWORD CSerialPort::GetCommEvents()
{
	return m_dwCommEvents;	
}

//
//	返回输出缓冲区大小
//
DWORD CSerialPort::GetWriteBufferSize()
{
	return m_nWriteBufferSize;
}



//
//	ReadBlock 采用与ReceiveChar 不同的由用户显示调用的方式读取窗口	
//
BYTE* CSerialPort::	ReadBlock(CSerialPort* 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:
				{
					bRead=FALSE;
					break;
				}
			default:
				{
					//其他错误返回值显示错误信息
					port->ProcessErrorMessage("ReadFile()");
					break;
				}
			}	// end if switch
		}	//	end if !bResult 
		else
		{
			//读操作已完成,不必再调用GetOverlappedResults()
			bRead=TRUE;
			
		}
		
	}	//	end if bRead
	
	if(!bRead)
	{
		bRead=TRUE;
		//继续完成读操作
		bResult=GetOverlappedResult(port->m_hComm,
			&port->m_ov,
			&BytesRead,
			TRUE);
		//错误处理
		if(!bRead)
		{
			port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
		}
	}	// end if (!Read)
	
	LeaveCriticalSection(&port->m_csCommunicationSync);	//	离开临界区
	
	readLen=BytesRead;	//	返回实际读取的字节数
	
	return pRec;
}

⌨️ 快捷键说明

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