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

📄 serial.cpp

📁 完整的windows ce下PPC通讯测试程序.
💻 CPP
字号:
// Serial.cpp

#include "stdafx.h"
#include "Serial.h"


CSerial::CSerial()
{
	// Initialize all its compenents
	// parity verify
	m_Parity = EVENPARITY;
	// Data bits
	m_DataBits = 8;
	// Stop Bits
	m_StopBits = ONESTOPBIT;
	// Baud Rate
	m_BaudRate = 9600;
	// Serial Port
	m_SerialPortNo = 1;
	// Read Buffer
	//ZeroMemory(m_ReadBuffer,BUFFERLENGTH);
	// Set NULL to m_hIDComDev
	m_hIDComDev = NULL;
	// timeout number
	m_nTimeOut = 1500;

	memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
 	memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
	m_hIDComDev = NULL;
	m_bOpened = FALSE;

}

CSerial::~CSerial()
{
	Close();
}

BOOL CSerial::Open( int nPort, int nBaud )
{

	if( this->m_bOpened ) return( TRUE );

	CString szPort;
	DCB dcb;

	this->m_SerialPortNo = nPort;
	szPort = "COM";
	if(nPort >= 10)
	{
		szPort += (char)(0x30 + nPort);
	}
	else
	{
		szPort += (char)(0x30+nPort%10);
		szPort += ':';
	}
	m_hIDComDev = CreateFile(	szPort,
								GENERIC_READ | GENERIC_WRITE,
								0,
								NULL,
								OPEN_EXISTING,
								0,//FILE_ATTRIBUTE_NORMAL,
								NULL );

	if( m_hIDComDev == INVALID_HANDLE_VALUE )
	{
		AfxMessageBox(_T("串口已经被占用,请关闭占用串口的程序,然后重新启动本系统。"));
		return( FALSE );
	}
	memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
 	memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );

	COMMTIMEOUTS CommTimeOuts;
	CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
	CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
	CommTimeOuts.ReadTotalTimeoutConstant = 0;
	CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
	CommTimeOuts.WriteTotalTimeoutConstant = 5000;
	SetCommTimeouts( m_hIDComDev, &CommTimeOuts );

	m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
	m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

	GetCommState( m_hIDComDev, &dcb );
	dcb.DCBlength = sizeof( DCB );

	// Baud Rate
	dcb.BaudRate = m_BaudRate;
	// Data bits
	dcb.ByteSize = m_DataBits;
	// Stop Bits
	dcb.StopBits = m_StopBits;
	// parity verify
	dcb.Parity = m_Parity;

	unsigned char ucSet;
	ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
	ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
	ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
	if( !SetCommState( m_hIDComDev, &dcb ) ||
		!SetupComm( m_hIDComDev, 10000, 10000 ) ||
		m_OverlappedRead.hEvent == NULL ||
		m_OverlappedWrite.hEvent == NULL )
	{
		/*
		DWORD dwError = GetLastError();

		LPVOID lpMsgBuf; //Windows will allocate 
		::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,0, GetLastError(), 
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //默认语言
		(LPTSTR)&lpMsgBuf, 0, NULL );

		//显示
		::MessageBox(0, (LPCTSTR)lpMsgBuf, ("GetLastError"), MB_OK|MB_ICONINFORMATION );

		//释放内存
		::LocalFree( lpMsgBuf );

		if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
		if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
		CloseHandle( m_hIDComDev );
		return( FALSE );
		*/
	}

	m_bOpened = TRUE;

	return( m_bOpened );

}

// Close the COM port specified by User, and set NULL to handle
BOOL CSerial::Close( void )
{

	if( !m_bOpened || m_hIDComDev == NULL ) return( TRUE );

	if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
	if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
	CloseHandle( m_hIDComDev );
	m_bOpened = FALSE;
	m_hIDComDev = NULL;

	return( TRUE );

}

BOOL CSerial::WriteCommByte( unsigned char ucByte )
{
	BOOL bWriteStat;
	DWORD dwBytesWritten;

	bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );
	/*
	if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) )
	{
		if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) )
		{
			dwBytesWritten = 0;
		}
		else
		{
			GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
			m_OverlappedWrite.Offset += dwBytesWritten;
		}
	}
	*/

	return( TRUE );

}

int CSerial::SendData( const unsigned char *buffer, int size ,BOOL isUpComm)
{
	if( !m_bOpened || m_hIDComDev == NULL )
		return( 0 );
	DWORD dwBytesWritten = 0;
	int i;
	for( i=0; i<size; i++ )
	{
		WriteCommByte( buffer[i] );
		dwBytesWritten++;
		if(!isUpComm)
		{
			Sleep(5);
		}
	}

	return( (int) dwBytesWritten );

}

int CSerial::ReadDataWaiting( void )
{

	if( !m_bOpened || m_hIDComDev == NULL )
		return( 0 );

	DWORD dwErrorFlags;
	COMSTAT ComStat;

	ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );

	return( (int) ComStat.cbInQue );

}

int CSerial::ReadData( void *buffer, int limit )
{

	if( !m_bOpened || m_hIDComDev == NULL )
		return( 0 );

	BOOL bReadStatus;
	DWORD dwBytesRead, dwErrorFlags;
	COMSTAT ComStat;

	ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
	if( !ComStat.cbInQue )
		return( 0 );

	dwBytesRead = (DWORD) ComStat.cbInQue;
	if( limit < (int) dwBytesRead )
		dwBytesRead = (DWORD) limit;

	bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
	if( !bReadStatus )
	{
		if( GetLastError() == ERROR_IO_PENDING )
		{
			WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
			return( (int) dwBytesRead );
		}
		return( 0 );
	}

	return( (int) dwBytesRead );

}


void CSerial::SetBaudRate(int BaudRate)
{
        // CBR_110 CBR_19200 CBR_300 CBR_38400 CBR_600 CBR_56000 CBR_1200 CBR_57600 CBR_2400
        // CBR_115200 CBR_4800 CBR_128000 CBR_9600 CBR_256000 CBR_14400
	this->m_BaudRate = BaudRate;
}

void CSerial::SetStopBits(BYTE nSettings)
{
	// nSettings = ONESTOPBIT | ONE5STOPBITS | TWOSTOPBITS
        if ((nSettings != ONESTOPBIT) && (nSettings != ONE5STOPBITS) && (nSettings !=TWOSTOPBITS))
                this->m_StopBits = ONESTOPBIT;
        else
        	this->m_StopBits = nSettings;
}

void CSerial::SetDataBits(BYTE nSettings)
{
	// nSettings = 8,7,6,5
        if ((nSettings != 8) && (nSettings != 7) && (nSettings != 6) && (nSettings != 5))
                this->m_DataBits = 8;
        else
        	this->m_DataBits = nSettings;
}

void CSerial::SetParity(BYTE bParitySettings)
{
	// bParitySettings = 	EVENPARITY Even
	//						MARKPARITY Mark
	//						NOPARITY No parity
	//						ODDPARITY Odd
	//						SPACEPARITY Space
        if (    (bParitySettings != EVENPARITY) &&
                (bParitySettings != MARKPARITY) &&
                (bParitySettings != NOPARITY) &&
                (bParitySettings != ODDPARITY) &&
                (bParitySettings != SPACEPARITY))
                this->m_Parity = NOPARITY;
        else
        	this->m_Parity = bParitySettings;
}

int unstrcat(unsigned char *ss1,int ss1Length,unsigned char *ss2,int ss2Length)
{
	int i;
	for (i=0;i<ss2Length;i++)
	{
		*(ss1+ss1Length+i) = *(ss2+i);
	}
	return ss1Length+ss2Length;
}

BOOL CSerial::SendCommand(unsigned char *sCommand,unsigned char *sCommandHeader, int nCommandLength, int nCommandHeaderLength, int nRespondLength)
{
	int lens = 0;
	int i,j,lnTimes = 0;
	int lnCommandRespondPointer = 0;
	unsigned char lsBuffer[BUFFERLENGTH];
	BOOL lbIsRespondHeader ;
	int lulen = 0;

	//ZeroMemory(this->m_ReadBuffer,BUFFERLENGTH);
	this->SendData(sCommand,nCommandLength,TRUE);
	for(lnTimes = 0 ; lnTimes < 500 ; lnTimes++)
	{
		if (lens < nRespondLength)
		{
			Sleep(5);
			//ZeroMemory(lsBuffer,BUFFERLENGTH);
			lens += this->ReadData(lsBuffer,BUFFERLENGTH);
			//strcat(this->m_ReadBuffer,lsBuffer);
			lulen = unstrcat(this->m_ReadBuffer,lulen,lsBuffer,lens);
			lnTimes ++;
		}
		else
		{
			// Seek the header of the command respond
			for(i=0;i<lens;i++)
			{
				lbIsRespondHeader = TRUE;
				for(j=0;j<nCommandHeaderLength;j++)
				{
					if((this->m_ReadBuffer[i+j] != *(sCommandHeader+j)) && (lbIsRespondHeader))
						lbIsRespondHeader = FALSE;
				}
				if (lbIsRespondHeader)
				{
					// command respond header has been found
					lnCommandRespondPointer =i;
					i= lens+1;
					j=nCommandHeaderLength+1;
				}
			}
			// get the command respond string (first byte of buffer = first byte of respond)
			// strcat(this->m_ReadBuffer,lsBuffer+lnCommandRespondPointer);
			lulen = unstrcat(m_ReadBuffer,lulen,lsBuffer+lnCommandRespondPointer,lens-lnCommandRespondPointer);
			// if the Respond command string length less than user specified length continue to read
			// if((int)strlen(this->m_ReadBuffer) >= nRespondLength)
			if (lulen >= nRespondLength)
			{
				return TRUE;
			}
		}
	}
	return FALSE;
}

/*
// send a query status command at first
// then read serial port buffer every 3ms,timeout 500 times
// if  no respond or respond string not longer enough after 500 times, operation failed and return FALSE
BOOL CSerial::GetCommandRespond(unsigned char *Command, int CommandLength, unsigned char *CommandRespondHeader, int CommandRespondHeaderLength, unsigned char *RespondBuffer, int RespondLength)
{
	int lntimes,i;
	BOOL lbResult = FALSE;
	int lnlen,lnHeader=0;
	unsigned char lsBuf[BUFFERLENGTH];
	unsigned char lsTempBuf[BUFFERLENGTH];
	int lnBufLength=0,lnTempBufLength=0;
	
	SendData(Command,CommandLength);
	ZeroMemory(lsBuf,BUFFERLENGTH);
 	for(lntimes =0;lntimes<this->m_nTimeOut;lntimes++)
	{
		Sleep(80);
		ZeroMemory(lsTempBuf,BUFFERLENGTH);
		lnTempBufLength = ReadData(lsTempBuf,BUFFERLENGTH);

		lnlen = unstrcat(lsBuf,lnBufLength,lsTempBuf,lnTempBufLength);
		
		if (lnlen >= RespondLength)
		{
			if (lbResult == FALSE)
			{
				for(i=0;i<lnlen-RespondLength+1;i++)
				{
					if ((*(lsBuf+i)==*(CommandRespondHeader+0)) &&
						(*(lsBuf+i+1) == *(CommandRespondHeader+1)) &&
						(*(lsBuf+i+2) == *(CommandRespondHeader+2)))
					{
						lnHeader = i;
						i=1500;
						lbResult = TRUE;
					}
				}
			}
			if(((lnlen - lnHeader) >= RespondLength) &&
				(lbResult == TRUE))
			{
				unstrcat(this->m_ReadBuffer,0,lsBuf+lnHeader,lnlen - lnHeader);
				unstrcat(RespondBuffer,0,lsBuf+lnHeader,lnlen - lnHeader);
				return lbResult;
			}
		}
	}

	unstrcat(this->m_ReadBuffer,0,lsBuf+lnHeader,lnlen - lnHeader);
	unstrcat(RespondBuffer,0,lsBuf+lnHeader,lnlen - lnHeader);
	return lbResult;
}
*/

// send a query status command at first
// then read serial port buffer every 3ms,timeout 500 times
// if  no respond or respond string not longer enough after 500 times, operation failed and return FALSE
BOOL CSerial::GetCommandRespond(unsigned char *Command, int CommandLength, unsigned char *CommandRespondHeader, int CommandRespondHeaderLength, unsigned char *RespondBuffer, int RespondLength)
{
	BOOL lbResult = FALSE;
	BOOL lbisFound = FALSE;
	int i;
	unsigned char lsReturnBuffer[2000];
	unsigned char lsTempBuffer[2000];
	int lnReturnBufferLength = 0,lnTempBufferLength = 0;
	int lnRespondHeaderPos;
	int m;

	//PurgeComm(this->m_hIDComDev, PURGE_RXCLEAR);
	//this->SendData(Command,CommandLength,TRUE);
	ZeroMemory(lsReturnBuffer,1500);

	//for(i=0;i<this->m_nTimeOut;i++)
	for(i=0;i<1000;i++)
	{
		// receive data from serial port every 3 ms 
		if((i % 10) == 0)
			Sleep(1);

		lnTempBufferLength = this->ReadData(lsTempBuffer,1500);

		for(m = 0;m < lnTempBufferLength;m++)
		{
			if (lnReturnBufferLength + m <= 1500)
			{
				*(lsReturnBuffer + lnReturnBufferLength + m) = *(lsTempBuffer + m);
			}
		}
		lnReturnBufferLength += lnTempBufferLength;

		// if receive data length equal or more than respond length, 
		// first step : find the header of respond string
		if (lnReturnBufferLength >= RespondLength)
		{
			for(m = 0;m < lnReturnBufferLength;m++)
			{
				if(memcmp(lsReturnBuffer+m,CommandRespondHeader,3) == 0)
				{
					// has found the header
					lnRespondHeaderPos = m;
					// end this circle
					m = lnReturnBufferLength;
					lbisFound = TRUE;
				}
			}
		}

		// second step : if the respond string is full , retur the respond string
		// and the lbResult = TRUE;
		if (((lnReturnBufferLength - lnRespondHeaderPos) >= RespondLength) && (lbisFound))
		{
			// copy the respond data to the return parameter
			for (m = 0;m < RespondLength;m++)
			{
				*(RespondBuffer + m) = *(lsReturnBuffer + lnRespondHeaderPos + m);
			}
			lbResult = TRUE;
			return lbResult;
		}
	}
	//return lbResult;
	return FALSE;
}

void CSerial::GetRespondBuffer(unsigned char *sRespond)
{
	// strcpy(sRespond,this->m_ReadBuffer);
	unstrcat(sRespond,0,m_ReadBuffer,m_ReadBufferLength);
}

void CSerial::SetTimeOutNumber(int nTimeOut)
{
	this->m_nTimeOut = nTimeOut;
}

void CSerial::GetCurrentStatus()
{
	DCB ldcb;
	::GetCommState(this->m_hIDComDev,&ldcb);
	this->m_BaudRate = ldcb.BaudRate;
	this->m_DataBits = ldcb.ByteSize;
	this->m_StopBits = ldcb.StopBits;
	this->m_Parity = ldcb.Parity;
}


BOOL CSerial::SetCurrentState()
{
	DCB dcb;
	dcb.DCBlength = sizeof( DCB );
	GetCommState( m_hIDComDev, &dcb );

	// Baud Rate
	dcb.BaudRate = m_BaudRate;
	// Data bits
	dcb.ByteSize = m_DataBits;
	// Stop Bits
	dcb.StopBits = m_StopBits;
	// parity verify
	dcb.Parity = m_Parity;

	return ::SetCommState(this->m_hIDComDev,&dcb);
}

void CSerial::SetSerialPortNo(int nSerial)
{
	this->m_SerialPortNo = nSerial;
}

⌨️ 快捷键说明

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