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

📄 serial.cpp

📁 路透串口通讯程序
💻 CPP
字号:
// Serial.cpp

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

CSerial::CSerial()
{
	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( m_bOpened ) return( TRUE );

	char szPort[15];
	char szComParams[50];
	DCB dcb;

	wsprintf( szPort, "COM%d", nPort );
	m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
	if( m_hIDComDev == NULL ) 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 );

	wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud );

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

	dcb.DCBlength = sizeof( DCB );
	GetCommState( m_hIDComDev, &dcb );
	dcb.BaudRate = nBaud;
	dcb.ByteSize = 8;
	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();
		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 );

}

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 )
{

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

	DWORD dwBytesWritten = 0;
	int i;
	for( i=0; i<size; i++ ){
		WriteCommByte( buffer[i] );
		dwBytesWritten++;
		}

	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 );

}

int CSerial::SendPacket(unsigned char *buf, int packlen)
{
	unsigned char buffer[1024];
	int i;
	char tmp[4];
	
	if(packlen > 1000)
		return 0;
	
	buffer[0] = 0x02; 
	sprintf(tmp, "%04d", packlen);
	buffer[1] = (tmp[0]<<4)+(tmp[1]&0x0f);
	buffer[2] = (tmp[2]<<4)+(tmp[3]&0x0f);

	memcpy(buffer+0, buf, packlen);

	buffer[packlen+0] = 0x03; 

	buffer[packlen+0] = 0;
	for(i=1;i<packlen+0;i++)
		buffer[packlen+0] ^= buffer[i];

	for(i=0;i<packlen+5;i++)
		sprintf(tmp+2*i, "%02x", buffer[i]);
	AfxMessageBox(tmp);

	if(SendData((unsigned char*)buffer, packlen+0) != packlen+5)
		return 0;

	return packlen;

}

int CSerial::SendACK()
{
	unsigned char buffer[1024];
	
	buffer[0] = 0x06; 

	if(SendData((unsigned char*)buffer, 1) != 1)
		return -1;
   
	return 0;
}

int CSerial::SendPack(int PackCode, int TicketId)
{
	unsigned char buffer[1024];
	int i, packlen;
	int mask = 0x8000;
	int GetElse = 0x7FFF;
	int count = 0;
	int temp = 0;
	int len = 0;
	char tempstr[20];
	
	memset(buffer, 0, sizeof(buffer));
	buffer[0] = 0x02;  //---<STX>
	buffer[1] = 0x1C;  //---<FS>
    sprintf(tempstr, "%d", PackCode);
	memcpy((char *)(buffer+2), tempstr, strlen(tempstr)); //--PackCode
	buffer[5] = 0x1F;  //---<US>

	if (PackCode == 332)
	{
		memcpy(buffer+6,"AA", 2);
		buffer[8] = 29;
		char temp[20];
		//memcpy(buffer+9, "BCCB#INFO", 9);
		sprintf(temp, "BCCB#%d", TicketId);
		memcpy(buffer+9, temp, strlen(temp));
		packlen = strlen((char *)buffer)+2;
	}

	if (PackCode == 333)
	{
		memcpy(buffer+6, "AA", 2);
		buffer[8] = 29;
		char temp[20];
		sprintf(temp, "BCCB#%d", TicketId);
		memcpy(buffer+9, temp, strlen(temp));
		packlen = strlen((char *)buffer)+2;
	}  

	buffer[packlen - 2] = 0x1C;
	buffer[packlen - 1] = 0x03; //---<ETX>

	for(i=1 ;i <= packlen ; i++)
        count = count + buffer[i];

	if (count > 0xFF)
	{
		if ((count & 0xFF) & 0x80)
		  buffer[packlen]= count & 0x7F;
		else
		  buffer[packlen]= count & 0xF7F;
	}
	else
	{
		for (i=0 ; i < 16 ; i++, mask >>=1 , GetElse >>=1)
		{
			if (count & mask)  //如果与mask大与零,则取最高位后的所有的位
			{
				temp = count & GetElse;
				buffer[packlen] = temp;
				break;
			}
		}
	}
	if(SendData((unsigned char*)buffer, packlen+1) != packlen+1)
		return -1;

	SetListInfo((char *)buffer);

	return packlen+1;
}

int CSerial::ReceivePacket(unsigned char *buf)
{
	unsigned char buffer[1024];
	char tmp[1000];
	int packlen,len,len1,i;
	CString  b;
	DWORD timeout;
	
	memset(buffer, 0, sizeof(buffer));
	len = len1 = 0;
	
	do{
		ReadData(buffer+len, 1);
	}while(buffer[0] != 0x02);


	for(i=1;i<3;i++)
		ReadData(buffer+i, 1);

	tmp[0] = (buffer[1]>>4)+'0';
	tmp[1] = (buffer[1]&0x0f)+'0';
	tmp[2] = (buffer[2]>>4)+'0';
	tmp[3] = (buffer[2]&0x0f)+'0';
	tmp[4] = 0;

	packlen = atoi(tmp);

	if(packlen > 1000)
		return 0;

	timeout = GetTickCount();
	len = 3;
	do{
		len1 = ReadData(buffer+len, 1024);
		len += len1;
		if((GetTickCount()-timeout)>2000)
			{AfxMessageBox("TimeOut!");return(0);}
	}while(len < packlen+5);

/*
	for(i=0;i<packlen+5;i++)
		sprintf(tmp+2*i, "%02x", buffer[i]);
	AfxMessageBox(tmp);
*/

	buffer[1023] = 0;
	for(i=1;i<packlen+4;i++)
		buffer[1023] ^= buffer[i];
	if(buffer[1023] != buffer[packlen+4])
		{AfxMessageBox("LRC ERROR!");return 0;}
		
	memcpy(buf, buffer+3, len-5);

	return packlen;

}

int CSerial::ReceivePack(unsigned char *buf)
{
	unsigned char buffer[3000];
	char tmp[1000];
	int len,len1,i;
	CString  b;
	DWORD timeout;
	int mask = 0x8000;
	int GetElse = 0x7FFF;
	int GetCheckNumber = 0xFF;  //Get 8 bit
	int count = 0;        //从STX后一位到ETX的总和
	int temp;         //两者进行与以后大于零时的总次数;
	
	memset(buffer, 0, sizeof(buffer));
	memset(tmp, 0, sizeof(tmp));
	
	len = len1 = 0;
	
	//接收包头字符
	do{
		ReadData(buffer+len, 1);
	}while(buffer[0] != 0x02);  
	
	timeout = GetTickCount();
    len1= len = 1;
	do 
	{
		len1 = ReadData(buffer+len, 1);
		len += len1;
		if((GetTickCount()-timeout)>1000)
			break;
	}
	while(buffer[len-1] != 3);

	ReadData(buffer+len, 1);

	//取包文所有字符的和
	for(i=1; i < len ; i++)
		count = count + buffer[i];

	int Begin8Bit;
	Begin8Bit = count & GetCheckNumber;

	if (count > GetCheckNumber)
		count = count & GetCheckNumber;

	memcpy(buf, buffer, len+1);

	if (buffer[len] == Begin8Bit || buffer[len] == count || buffer[len] == 0)
		return len+1;

    for (i=0 ; i < 16 ; i++, mask >>=1 , GetElse >>=1)
	{
       if (count & mask)  //如果与mask大与零,则取最高位后的所有的位
	   {
           temp = count & GetElse;
           if (buffer[len] == temp )
			   break;
		   else
		   {
              SetListInfo("包文错误!");
              //return -1;
		   }
	   }
	}

	return len+1;
}

int CSerial::ReceiveACK()
{
	DWORD timeout;
	unsigned char buffer[3000];
	
	timeout = GetTickCount();
	do{
		ReadData(buffer, 1);

		if((GetTickCount()-timeout)>1000)
			return -1;

	}while(buffer[0] != 0x06);  

    return 0;
}

 
int CSerial::UnpackRecData(unsigned char * buffer, int packlen, long TicketNumber)
{
	FILE *fp;
	char filename[80],pathname[80], temp[80];
	int TicketId=0;
	bool BeginRec=false;
	
	int first=0, last=0;
	int LineCount=0;
    
	memset(temp, 0, sizeof(temp));
	memcpy(temp, (char *)(buffer+2), 3);
	if (atoi(temp) != 340)
		return atoi(temp);

	memset(pathname, 0, sizeof(pathname));
	if (GetPrivateProfileString("FILE", "PackDataFilePath ", NULL, pathname, sizeof(pathname), ".\\config.ini") < 0)
	{
		AfxMessageBox("Cann't open config file!");
		return -1;
	} 
  
	memset(filename, 0, sizeof(filename));
	sprintf(filename, "%s\\%06ld.txt", pathname, TicketNumber);
	if ((fp = fopen(filename, "wb")) == NULL)
	{   
		sprintf(temp, "打不开文件%s!", filename);
		SetListInfo(temp);
		return -1;
	}
	
	for(int i=0 ; i< packlen; i++)
	{
		if (buffer[i] == 0x03)
			break;

		if (buffer[i] == 0x1C)
			continue;

		if (buffer[i] == 0x1E && first < last)
		{
			memset(temp, 0, sizeof(temp));
			memcpy(temp, buffer+first, i - first );
			for(int j=0; j< (int)strlen(temp); j++)
			{
				if(temp[j] == 0x1F) //<US> to blank
					temp[j] = ' ';
			}
			
			fprintf(fp, "%s\n", temp);
			LineCount ++;  //计算写入文件的行数
			
		}

		if (buffer[i] == 0x1E ) //<RS>
		{
			//if(first == last && first == 0)
			first = last = i+1;

			BeginRec = true;
			continue;
		}
		
		if (BeginRec == true)
			last ++;

	}
	
	fclose(fp);

	return 340;
}

⌨️ 快捷键说明

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