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

📄 serialportbase.cpp

📁 serial port io rw wce w32
💻 CPP
字号:
// CSerialPortBase.cpp: implementation of the CSerialPortBase class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <process.h>
#include "SerialPortBase.h"

unsigned int _stdcall CSerialPortBase::ThreadFunc( void* pArg )
{
	CSerialPortBase* pSerialPortBase = (CSerialPortBase*) pArg;

	return pSerialPortBase->Run();
}

BOOL	CSerialPortBase::SetPortName(LPCTSTR strPortName)
{
	if ( IsThreadRunning() )
	{
		return	FALSE;
	}
	else
	{
		int len = strlen(strPortName);
		if ( len <10 )
		{
			for ( int i=0; i<=len; i++ )
			{
				m_strPortName[i]=strPortName[i];
			}
			return	TRUE;
		}
		else
		{
			return	FALSE;
		}
	}
}

unsigned int CSerialPortBase::Run()
{
	m_bRunning = OnStartup();
	EventLoop2();
	OnShutdown();
	m_hThread	= INVALID_HANDLE_VALUE;
	return 0;
}


DWORD CSerialPortBase::StartThread( void )
{
	if ( IsRunning() )
	{
		TRACE("The thread 0x%0X is already runnung\n", m_nThreadID);
		return	0;
	}	

	// Create the thread
	m_hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadFunc, this, 0, &m_nThreadID ); 

	if ( m_hThread == INVALID_HANDLE_VALUE )
	{
		// Error creating thread
		m_bRunning = FALSE;
		TRACE("The thread start failed\n");
		return -1;
	}
	else
	{
		TRACE("The thread 0x%0X has started\n", m_nThreadID);
		// Success
		m_bRunning = TRUE;
		return 0;
	}
}

void CSerialPortBase::StopThread()
{
	if ( IsRunning() )
	{
		m_bRunning = FALSE;
	}
	
	if ( IsThreadRunning() )
	{
		::WaitForSingleObject(GetHandle(), INFINITE);
	}
}

BOOL CSerialPortBase::OnStartup( void )
{

	if ( FALSE == SerialPortOpen(m_strPortName) )
		return	FALSE;

	if ( FALSE == ConfigurePort() )
		return	FALSE;

	if ( FALSE == ConfigureTimeOuts() )
		return	FALSE;

	return TRUE;
}

void CSerialPortBase::OnShutdown( void )
{
	SerialPortClose();
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSerialPortBase::CSerialPortBase()
:m_hThread(INVALID_HANDLE_VALUE)
,m_bRunning(FALSE)
,m_hSerialPort(INVALID_HANDLE_VALUE)
{
}

CSerialPortBase::~CSerialPortBase()
{
}

BOOL CSerialPortBase::SerialPortOpen(LPCTSTR lpszPortName)
{
//	if ( m_hSerialPort != INVALID_HANDLE_VALUE )
//	{
//		CloseHandle(m_hSerialPort);
//	}
	m_hSerialPort = ::CreateFile (lpszPortName, // Pointer to the name of the port
                      GENERIC_READ | GENERIC_WRITE,
                                    // Access (read-write) mode
                      0,            // Share mode
                      NULL,         // Pointer to the security attribute
                      OPEN_EXISTING,// How to open the serial port
                      0,            // Port attributes
                      NULL);        // Handle to port with attribute
                                    // to copy
	if ( m_hSerialPort == INVALID_HANDLE_VALUE )
	{
		TRACE("Err CreateFile!");
		return	FALSE;
	}
	else
	{
		return	TRUE;
	}
}

BOOL CSerialPortBase::ConfigurePort()
{
	DCB PortDCB;

	// Initialize the DCBlength member. 
	PortDCB.DCBlength = sizeof (DCB); 

	// Get the default port setting information.
	GetCommState (m_hSerialPort, &PortDCB);

	// Change the DCB structure settings.
	PortDCB.BaudRate = 9600;              // Current baud 
	PortDCB.fBinary = TRUE;               // Binary mode; no EOF check 
	PortDCB.fParity = TRUE;               // Enable parity checking 
	PortDCB.fOutxCtsFlow = FALSE;         // No CTS output flow control 
	PortDCB.fOutxDsrFlow = FALSE;         // No DSR output flow control 
	PortDCB.fDtrControl = DTR_CONTROL_ENABLE; 
										  // DTR flow control type 
	PortDCB.fDsrSensitivity = FALSE;      // DSR sensitivity 
	PortDCB.fTXContinueOnXoff = TRUE;     // XOFF continues Tx 
	PortDCB.fOutX = FALSE;                // No XON/XOFF out flow control 
	PortDCB.fInX = FALSE;                 // No XON/XOFF in flow control 
	PortDCB.fErrorChar = FALSE;           // Disable error replacement 
	PortDCB.fNull = FALSE;                // Disable null stripping 
	PortDCB.fRtsControl = RTS_CONTROL_ENABLE; 
										  // RTS flow control 
	PortDCB.fAbortOnError = FALSE;        // Do not abort reads/writes on 
										  // error
	PortDCB.ByteSize = 8;                 // Number of bits/byte, 4-8 
	PortDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space 
	PortDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2 

	// Configure the port according to the specifications of the DCB 
	// structure.
	if (!SetCommState (m_hSerialPort, &PortDCB))
	{
		// Could not configure the serial port.
		  return FALSE;
	}
	else
	{
		return	TRUE;
	}
}

BOOL CSerialPortBase::ConfigureTimeOuts()
{
	// Retrieve the time-out parameters for all read and write operations
	// on the port. 
	COMMTIMEOUTS CommTimeouts;
	GetCommTimeouts (m_hSerialPort, &CommTimeouts);

	// Change the COMMTIMEOUTS structure settings.
	CommTimeouts.ReadIntervalTimeout = MAXDWORD;  
	CommTimeouts.ReadTotalTimeoutMultiplier = MAXDWORD;  
	CommTimeouts.ReadTotalTimeoutConstant = 100;    
	CommTimeouts.WriteTotalTimeoutMultiplier = 10;  
	CommTimeouts.WriteTotalTimeoutConstant = 1000;    

	// Set the time-out parameters for all read and write operations
	// on the port. 
	if (!SetCommTimeouts (m_hSerialPort, &CommTimeouts))
	{
//		// Could not set the time-out parameters.
//		MessageBox (hMainWnd, TEXT("Unable to set the time-out parameters"), 
//					TEXT("Error"), MB_OK);
//		dwError = GetLastError ();
		return FALSE;
	}
	else
	{
		return	TRUE;
	}
}

void CSerialPortBase::SerialPortClose()
{
	CloseHandle(m_hSerialPort);
	m_hSerialPort = INVALID_HANDLE_VALUE;
}

void CSerialPortBase::EventLoop2()
{
	BYTE Byte;
	DWORD dwBytesTransferred;
	// Loop for waiting for the data.
	do 
	{
		// Read the data from the serial port.
		ReadFile (m_hSerialPort, &Byte, 1, &dwBytesTransferred, 0);

		// Display the data read.
		if (dwBytesTransferred == 1)
		{
			ProcessChar (Byte);
		}
		else
		{
			TRACE("TimeOut!\n");
		}
		Sleep(100);
	}
	while (m_hSerialPort != INVALID_HANDLE_VALUE  && m_bRunning ) ;
}

void CSerialPortBase::ProcessChar (TCHAR Byte)
{
	TRACE("AA ");
}

#if 0
void CSerialPortBase::EventLoop()
{
	DWORD dwCommModemStatus;

	// Specify a set of events to be monitored for the port.
	SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);

	while (m_hSerialPort != INVALID_HANDLE_VALUE  && m_bRunning ) 
	{
		// Wait for an event to occur for the port.
		WaitCommEvent (m_hSerialPort, &dwCommModemStatus, 0);
		TRACE("Passed WaitCommEvent!\n");

		// Re-specify the set of events to be monitored for the port.
		SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING);

		if( dwCommModemStatus & EV_CTS )		//#define EV_CTS              0x0008  // CTS changed state
		{
			//TRACE( "CSerialPortBase::OnCommEvent: CTS changed state\n" );
			OnCommEventCTS();
		}
		if( dwCommModemStatus & EV_ERR )		//#define EV_ERR              0x0080  // Line status error occurred
		{
			//TRACE( "CSerialPortBase::OnCommEvent: Error\n" );
			OnCommEventErr();
		}
		if( dwCommModemStatus & EV_DSR )		//#define EV_DSR              0x0010  // DSR changed state
		{
			//TRACE( "CSerialPortBase::OnCommEvent: DSR changed state\n" );
			OnCommEventDSR();
		}
		if( dwCommModemStatus & EV_RLSD )		//#define EV_RLSD             0x0020  // RLSD changed state
		{
			//TRACE( "CSerialPortBase::OnCommEvent: RLSD changed state\n" );
			OnCommEventRLSD();
		}
		if( dwCommModemStatus & EV_BREAK )	//#define EV_BREAK            0x0040  // BREAK received
		{
			//TRACE( "CSerialPortBase::OnCommEvent: Break detected\n" );
			OnCommEventBreak();
		}
		if( dwCommModemStatus & EV_TXEMPTY )	//#define EV_TXEMPTY          0x0004  // Transmitt Queue Empty
		{
			//TRACE( "CSerialPortBase::OnCommEvent: Transmitt Queue Empty\n" );
			OnCommEventTxEmpty();
		}
		if( dwCommModemStatus & EV_RXCHAR )	//#define EV_RXCHAR           0x0001  // Any Character received
		{
			//TRACE( "CSerialPortBase::OnCommEvent: Any Character received\n" );
			OnCommEventRxChar();
		}
		if( dwCommModemStatus & EV_RXFLAG )	//#define EV_RXFLAG           0x0002  // Received certain character
		{
			//TRACE( "CSerialPortBase::OnCommEvent: Received certain character\n" );
			OnCommEventRxFlag();
		}
		if( dwCommModemStatus & EV_RING )		//#define EV_RING             0x0100  // Ring signal detected
		{
			//TRACE( "CSerialPortBase::OnCommEvent: Ring signal detected\n" );
			OnCommEventRing();
		}
		if( dwCommModemStatus & EV_PERR )		//#define EV_PERR             0x0200  // Printer error occured
		{
			//TRACE( "CSerialPortBase::OnCommEvent: Printer error occured\n" );
			OnCommEventPERR();
		}
		if( dwCommModemStatus & EV_RX80FULL )		//#define EV_RX80FULL         0x0400  // Receive buffer is 80 percent full
		{
			//TRACE( "CSerialPortBase::OnCommEvent: Receive buffer is 80 percent full\n" );
			OnCommEventRx80Full();
		}
		if( dwCommModemStatus & EV_EVENT1 )		//#define EV_EVENT1           0x0800  // Provider specific event 1
		{
			//TRACE( "CSerialPortBase::OnCommEvent: Provider specific event 1\n" );
			OnCommEventEvent1();
		}
		if( dwCommModemStatus & EV_EVENT2 )		//#define EV_EVENT2           0x1000  // Provider specific event 2
		{
			//TRACE( "CSerialPortBase::OnCommEvent: Provider specific event 2\n" );
			OnCommEventEvent2();
		}
	}
	m_bRunning	= FALSE;
}

///////////////////////////////////////////////////////////////////////////////
//	Comm Event Handlers
///////////////////////////////////////////////////////////////////////////////
void CSerialPortBase::OnCommEventRxChar(void)
{				//#define EV_RXCHAR           0x0001  // Any Character received
	BYTE Byte;
	DWORD dwBytesTransferred;
	// Loop for waiting for the data.
	do 
	{
		// Read the data from the serial port.
		ReadFile (m_hSerialPort, &Byte, 1, &dwBytesTransferred, 0);

		// Display the data read.
		if (dwBytesTransferred == 1)
			ProcessChar (Byte);

	} while (dwBytesTransferred == 1);
}
void CSerialPortBase::OnCommEventRxFlag(void)	{}		//#define EV_RXFLAG           0x0002  // Received certain character
void CSerialPortBase::OnCommEventTxEmpty(void)	{}		//#define EV_TXEMPTY          0x0004  // Transmitt Queue Empty
void CSerialPortBase::OnCommEventCTS(void)		{}		//#define EV_CTS              0x0008  // CTS changed state
void CSerialPortBase::OnCommEventDSR(void)		{}		//#define EV_DSR              0x0010  // DSR changed state
void CSerialPortBase::OnCommEventRLSD(void)		{}		//#define EV_RLSD             0x0020  // RLSD changed state
void CSerialPortBase::OnCommEventBreak(void)		{}		//#define EV_BREAK            0x0040  // BREAK received
void CSerialPortBase::OnCommEventErr(void)		{}		//#define EV_ERR              0x0080  // Line status error occurred
void CSerialPortBase::OnCommEventRing(void)		{}		//#define EV_RING             0x0100  // Ring signal detected
void CSerialPortBase::OnCommEventPERR(void)		{}		//#define EV_PERR             0x0200  // Printer error occured
void CSerialPortBase::OnCommEventRx80Full(void)	{}		//#define EV_RX80FULL         0x0400  // Receive buffer is 80 percent full
void CSerialPortBase::OnCommEventEvent1(void)	{}		//#define EV_EVENT1           0x0800  // Provider specific event 1
void CSerialPortBase::OnCommEventEvent2(void)	{}		//#define EV_EVENT2           0x1000  // Provider specific event 2

///////////////////////////////////////////////////////////////////////////////
//	Write to Port
///////////////////////////////////////////////////////////////////////////////
BOOL CSerialPortBase::Write(LPCTSTR lpBuffer, DWORD nNumberOfBytesToWrite)
{
	DWORD dwNumBytesWritten;
	DWORD dwStart=0;
	while (dwStart < nNumberOfBytesToWrite )
	{
		if ( FALSE == WriteFile(m_hSerialPort, 
								&lpBuffer[dwStart],
								nNumberOfBytesToWrite - dwStart,
								&dwNumBytesWritten,
								NULL)		)
		{
			return FALSE;
		}
		else
		{
			dwStart+=dwNumBytesWritten;
		}
	}
	return	TRUE;
}

#endif

⌨️ 快捷键说明

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