myserial.cpp

来自「一个串行口通讯的例子程序」· C++ 代码 · 共 365 行

CPP
365
字号
// CMySerial class implementaion//#include <windows.h>#include "stdafx.h"#include <fstream.h>#include <stdio.h>#include "tty.h"#include "MySerial.h"CMySerial::CMySerial():m_nReadThread(0),m_dwError(0){	m_ReadingBuffer.dwLen=0;	m_ReadingBuffer.lpByte=NULL;	m_hSerial=INVALID_HANDLE_VALUE;}CMySerial::~CMySerial(){	if(m_hSerial!=INVALID_HANDLE_VALUE)		CloseSerial();}CMySerial::InitSerial(UINT nPort/*=1*/, UINT baud/*=2400*/, char parity/*='n'*/, 					UINT databits/*=8*/, UINT stopbits/*=1*/){	DCB PortDCB;	COMMTIMEOUTS CommTimeouts;		char buf[10];	sprintf(buf,"COM%d",nPort);	// Open the serial port.	m_hSerial = CreateFile (buf, // 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 it fails to open the port, return FALSE.	if ( m_hSerial == INVALID_HANDLE_VALUE ) 	{		// Could not open the port.		MessageBox (NULL, TEXT("Unable to open the port"), 			TEXT("Error"), MB_OK);		m_dwError = GetLastError ();		DisplayError();		return FALSE;	}		PortDCB.DCBlength = sizeof (DCB);     		// Get the default port setting information.	GetCommState (m_hSerial, &PortDCB);		// Change the DCB structure settings.	PortDCB.BaudRate = baud;              // Current baud 	PortDCB.fBinary = TRUE;               // Binary mode; no EOF check 	PortDCB.fParity = TRUE;               // Ensable 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 = databits;                 // Number of bits/bytes, 4-8 	if(parity=='n'||parity=='N')		PortDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space 	switch(stopbits)	{	case 1:		PortDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2 		break;	default:		PortDCB.StopBits = TWOSTOPBITS;		break;	}			// Configure the port according to the specifications of the DCB 	// structure.	if (!SetCommState (m_hSerial, &PortDCB))	{		// Could not configure the serial port.		MessageBox (NULL, TEXT("Unable to configure the serial port"), 			TEXT("Error"), MB_OK);		m_dwError = GetLastError ();		DisplayError();		return FALSE;	}		// Retrieve the time-out parameters for all read and write operations	// on the port. 	GetCommTimeouts (m_hSerial, &CommTimeouts);		// Change the COMMTIMEOUTS structure settings.	CommTimeouts.ReadIntervalTimeout = MAXDWORD;  	CommTimeouts.ReadTotalTimeoutMultiplier = 0;  	CommTimeouts.ReadTotalTimeoutConstant = 0;    	CommTimeouts.WriteTotalTimeoutMultiplier = 10;  	CommTimeouts.WriteTotalTimeoutConstant = 1000;    		// Set the time-out parameters for all read and write operations	// on the port. 	if (!SetCommTimeouts (m_hSerial, &CommTimeouts))	{		// Could not set the time-out parameters.		MessageBox (NULL, TEXT("Unable to set the time-out parameters"), 			TEXT("Error"), MB_OK);		m_dwError = GetLastError ();		DisplayError();		return FALSE;	}		// Direct the port to perform extended functions SETDTR and SETRTS.	// SETDTR: Sends the DTR (data-terminal-ready) signal.	// SETRTS: Sends the RTS (request-to-send) signal. 	EscapeCommFunction (m_hSerial, SETDTR);	EscapeCommFunction (m_hSerial, SETRTS);	return TRUE;}BOOL CMySerial::CloseSerial(){	if (m_hSerial != INVALID_HANDLE_VALUE)	{		// Close the communication port.		if (!CloseHandle (m_hSerial))		{			m_dwError = GetLastError ();			DisplayError();			return FALSE;		}		else		{			m_hSerial = INVALID_HANDLE_VALUE;			return TRUE;		}	}	return FALSE;}BOOL CMySerial::WritePort(BYTE byte){	DWORD dwNumBytesWritten;		if (!WriteFile (m_hSerial,              // Port handle		&byte,              // Pointer to the data to write 		1,                  // Number of bytes to write		&dwNumBytesWritten, // Pointer to the number of bytes 		// written		NULL))              // Must be NULL for Windows CE	{		// WriteFile failed. Report error.		m_dwError = GetLastError ();		DisplayError();		return FALSE;	}	return TRUE;}void CMySerial::DisplayError(void){	LPVOID lpMsgBuf;	FormatMessage( 		FORMAT_MESSAGE_ALLOCATE_BUFFER | 		FORMAT_MESSAGE_FROM_SYSTEM | 		FORMAT_MESSAGE_IGNORE_INSERTS,		NULL,		m_dwError,		0, // Default language		(LPTSTR) &lpMsgBuf,		0,		NULL 		);	MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );	// Free the buffer.	LocalFree( lpMsgBuf );}BOOL CMySerial::ReadPort(LPBYTE lpByte, DWORD dwLen/*=1*/, DWORD dwTimeLimit/*=2000*/){	if(m_nReadThread)	{		MessageBox(0,"已经有一个读串口的线程在工作!\n读串口请求被拒绝","ReadPort",MB_OK);		return FALSE;	}	else //m_nReadThread=0	{		InterlockedIncrement(&m_nReadThread); 	}	m_ReadingBuffer.dwLen=dwLen;	m_ReadingBuffer.lpByte=lpByte;	memset(m_ReadingBuffer.lpByte,0,m_ReadingBuffer.dwLen);	HANDLE hReadThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)ReadThread,this,0,0);	if(hReadThread)	{		DWORD dwRet=WaitForSingleObject(hReadThread,dwTimeLimit);		if(dwRet==WAIT_TIMEOUT)		{			MessageBox(NULL,TEXT("Read thread stopped because time out!"),TEXT("Error"),MB_OK);			m_dwError=GetLastError();			DisplayError();			m_ReadingBuffer.dwLen=0;			m_ReadingBuffer.lpByte=0;			InterlockedDecrement(&m_nReadThread);			return FALSE;		}	}	else	{		MessageBox (NULL, TEXT("Unable to create the read thread"), 			TEXT("Error"), MB_OK);		m_dwError = GetLastError ();		DisplayError();		m_ReadingBuffer.dwLen=0;		m_ReadingBuffer.lpByte=0;		InterlockedDecrement(&m_nReadThread);		return FALSE;	}	m_ReadingBuffer.dwLen=0;	m_ReadingBuffer.lpByte=0;	InterlockedDecrement(&m_nReadThread);	return TRUE;}UINT CMySerial::ReadThread(LPVOID pParam){	ofstream fout;	CMySerial *pPort=(CMySerial*)pParam;	DWORD dwCommModemStatus,		dwBytesTransferred;		// Specify a set of events to be monitored for the port.	SetCommMask (pPort->m_hSerial, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);		DWORD dwCount=0;	while ((pPort->m_hSerial != INVALID_HANDLE_VALUE) &&(dwCount<pPort->m_ReadingBuffer.dwLen))	{		// Wait for an event to occur for the port.		WaitCommEvent (pPort->m_hSerial, &dwCommModemStatus, 0);				// Re-specify the set of events to be monitored for the port.		SetCommMask (pPort->m_hSerial, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING);				if (dwCommModemStatus & EV_RXCHAR) 		{			// Loop for waiting for the data.			do 			{				// Read the data from the serial port.				ReadFile (pPort->m_hSerial, &pPort->m_ReadingBuffer.lpByte[dwCount], 1, 					&dwBytesTransferred, 0);								// Display the data read.				if (dwBytesTransferred == 1)				{					//receive a byte of data successfully					dwCount++;				} 			}			while (dwBytesTransferred == 1);		}						// Retrieve modem control-register values.		if(GetCommModemStatus (pPort->m_hSerial, &dwCommModemStatus)==FALSE)		{			pPort->m_dwError=GetLastError();			pPort->DisplayError();			fout.open("e:\\error.txt",ios::app);			fout<<pPort->m_dwError<<endl;			fout.close();		}	}		return 0;}double CMySerial::GetFrequency(){	if(WritePort(0x80)==FALSE)	{		AfxMessageBox("写串口失败!");		return 0;	}	BYTE lpByte[20];	memset(lpByte,0,20);	if(ReadPort(lpByte,12)==FALSE)	{		AfxMessageBox("读端口失败");		return 0;	}	int data[6];	data[5]=0;	double freq[6];	freq[5]=0;	for(int i=0;i<5;i++)	{			data[i]=256*((int)lpByte[2*i+3])+(int)lpByte[2*i+2];		freq[i]=((double)data[i])*20.10370;	}	int max,min;	MaxMin(data,5,max,min);	for(i=0;i<5;i++)	{		if((i==max)||(i==min))			continue;		else		{			data[5]+=data[i];			freq[5]+=freq[i];		}	}	data[5]/=3;	freq[5]/=3;//	COleDateTime time=::COleDateTime::GetCurrentTime();//	char buffer[512];//	sprintf(buffer,"%2d时%2d分%2d秒: %2x%2x %2x%2x %2x%2x %2x%2x %2x%2x : %lf",//		time.GetHour(),time.GetMinute(),time.GetSecond(),lpByte[3],lpByte[2],lpByte[5],//		lpByte[4],lpByte[7],lpByte[6],lpByte[9],lpByte[8],lpByte[11],lpByte[10],freq[5]);//	ofstream fout("e:\\data0.txt",ios::app);//	fout<<buffer<<endl;//	fout.close();	return freq[5];}void CMySerial::MaxMin(int *pInt, int len, int &max, int &min){	max=0;	min=0;	for(int i=0;i<len;i++)	{		if(pInt[i]>pInt[max])				max=i;		if(pInt[i]<pInt[min])			min=i;	}}

⌨️ 快捷键说明

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