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

📄 serialport.cpp

📁 SerialPort_C++Builder
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				break; 
			}
		} // end switch
		
		port->ReportModemStat(port,FALSE); //lvfeng add
    } // close forever loop
    return 0;
}

void TSerialPort::ReportModemStat(TSerialPort *port, BOOL bUpDataNow) //lvfeng add
{
    //__declspec(thread)
    static DWORD dwOldStatus = 0;
	DWORD dModemStat = 0;
	if (!GetCommModemStatus(port->m_hComm,&dModemStat))
		port->ProcessErrorMessage("GetCommModemStatus()");
	//
	// Report status if status has changed
	//
	if ( bUpDataNow || (dModemStat != dwOldStatus))
	{
		//TRACE(" dModemStat = 0x%08x \n",dModemStat);
		::SendMessage(port->m_pOwner->Handle, WM_COMM_MODEM_STATUS, (WPARAM) dModemStat, (LPARAM) port->m_nPortNr);
		dwOldStatus = dModemStat;
	}
}
// 
// start comm watching 
// 
BOOL TSerialPort::StartMonitoring() 
{ 
	DWORD lpThreadId;
	m_HThread =CreateThread(NULL, 
		                    0,
		                    CommThread,
	                    	this,
	                    	0,
	                    	&lpThreadId); 
	if(m_HThread==NULL) 
	{ 
		ProcessErrorMessage("Create Thread Error"); 
		return false;
	} 
	return true;
} 

// 
// Restart the comm thread 
// 
// 
BOOL TSerialPort::RestartMonitoring()
{ 
	ResumeThread(m_HThread);
	return true;
} 

// 
// Suspend the comm thread 
// 
BOOL TSerialPort::StopMonitoring()
{ 
	SuspendThread(m_HThread); 
	return true;
} 

// 
// If there is a error, give the right message 
// 
void TSerialPort::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); 
	Application->MessageBox(Temp, "Application Error", MB_ICONSTOP);
	
	LocalFree(lpMsgBuf); 
	delete[] Temp; 
}
//
// Write a character. 
// 
void TSerialPort::WriteChar(TSerialPort* 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
                            //strlen((char*)port->m_szWriteBuffer),   // Length of message to send  lvfeng delete
                            port->m_nWriteSize, //lvfeng add
                            &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 
	if (BytesSent != DWORD(port->m_nWriteSize))//(BytesSent != strlen((char*)port->m_szWriteBuffer))
	{ 
		printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)port->m_szWriteBuffer)); 
	}
    ::SendMessage(port->m_pOwner->Handle, WM_COMM_TXEMPTY_DETECTED,0,(LPARAM) port->m_nPortNr);
    }

// 
// Character received. Inform the owner
// 
void TSerialPort::ReceiveChar(TSerialPort* port, COMSTAT comstat)
{ 
	BOOL bRead = true; 
	BOOL bResult = true;
	DWORD dwError = 0;
	DWORD BytesRead = 0; 
	unsigned char RXBuff; 
		
	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 
			break; 
		} 
		
		EnterCriticalSection(&port->m_csCommunicationSync); 
		
		if (bRead) 
		{ 
			bResult = ReadFile(port->m_hComm,   // Handle to COMM port
                            &RXBuff,            // RX Buffer Pointer
				            1,                  // 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. 
						port->ProcessErrorMessage("ReadFile()"); 
						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)
			{ 
				port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()"); 				
			}
		} // close if (!bRead) 
		
		LeaveCriticalSection(&port->m_csCommunicationSync); 
		
		// notify parent that a byte was received 
		::SendMessage(port->m_pOwner->Handle, WM_COMM_RXCHAR, (WPARAM) RXBuff, (LPARAM) port->m_nPortNr);
	} // end forever loop 
	
} 

void TSerialPort::WriteToPort(LPCTSTR string) //lvfeng add
{
	assert(m_hComm != 0);
	
	memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
	strcpy(m_szWriteBuffer, string);
	m_nWriteSize=strlen(string);
	
	// set event for write
	SetEvent(m_hWriteEvent);
}
// 
// Write a string to the port 
// 
void TSerialPort::WriteToPort(char* string)
{ 
	assert(m_hComm != 0);
	
	memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer)); 
	strcpy(m_szWriteBuffer, string); 
	
	//
	m_nWriteSize=strlen(string);
	// set event for write 
	SetEvent(m_hWriteEvent); 
} 

void TSerialPort::WriteToPort(unsigned char* TxdBuffer, int len) //lvfeng add
{
	assert(m_hComm!=0);

	memset(m_szWriteBuffer,0,sizeof(m_szWriteBuffer));
	memcpy(m_szWriteBuffer,TxdBuffer,len);
	m_nWriteSize=len;	
	//set event for write
	SetEvent(m_hWriteEvent);
}
//
// Return the device control block 
// 
DCB TSerialPort::GetDCB()
{ 
	return m_dcb; 
} 

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

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

//lvfeng add
void TSerialPort::Close()
{
	do
	{
		SetEvent(m_hShutdownEvent);
	} while (m_bThreadAlive);
	
	if(m_ov.hEvent !=NULL)
		CloseHandle(m_ov.hEvent );		
	printf("CommPort Close\n");
	m_bCommStatus = FALSE;
}

BOOL TSerialPort::IsOpen() //lvfeng add
{
	return m_bCommStatus;
}

BOOL TSerialPort::SetDTR()		//设置 DTR 为ON(+3V ~ +15V)
{
	return EscapeCommFunction(m_hComm,SETDTR);
}

BOOL TSerialPort::ClrDTR()		//清除 DTR 为OFF(-3V ~ -15V)
{
	return EscapeCommFunction(m_hComm,CLRDTR);
}

BOOL TSerialPort::SetRTS()		//设置 RTS 为ON(+3V ~ +15V)
{
	return EscapeCommFunction(m_hComm,SETRTS);
}

BOOL TSerialPort::ClrRTS()		//清除 RTS 为OFF(-3V ~ -15V)
{
	return EscapeCommFunction(m_hComm,CLRRTS);
}

⌨️ 快捷键说明

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