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

📄 serialport.cpp

📁 串口操作类
💻 CPP
字号:
// SerialPort.cpp: implementation of the CSerialPort class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SerialPort.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSerialPort::CSerialPort()
{
	m_hComm = INVALID_HANDLE_VALUE;
	m_dwBaudRate = CBR_9600;
}

CSerialPort::~CSerialPort()
{
	if (m_hComm != INVALID_HANDLE_VALUE)
		Close();
}

void CSerialPort::Open(UINT nPort /*=1*/)
{
	CString strPort;
	strPort.Format("COM%d", nPort);
	m_hComm = CreateFile(strPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (m_hComm == INVALID_HANDLE_VALUE)
	{
		CString strText;
		strText.Format("打不开串行口(COM%d)!\r\n请检查!", nPort);
		MessageBox(NULL, strText, "错误", MB_SYSTEMMODAL | MB_ICONERROR);
		return;
	}

	// Get any early notifications.
	SetCommMask(m_hComm, EV_RXCHAR);
	// Setup device buffers.
	SetupComm(m_hComm, 1024, 1024);
	// Purge any information in the buffer.
	PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

	COMMTIMEOUTS commtimeouts;
	commtimeouts.ReadIntervalTimeout		=	0xFFFFFFFF;	// 两字符之间最大的延时,当读取串口数据时,一旦两个字符传输的时间差超过该时间,读取函数将返回现有的数据。设置为0表示该参数不起作用。 
	commtimeouts.ReadTotalTimeoutMultiplier	=	50;			// 读取每字符间的超时。
	commtimeouts.ReadTotalTimeoutConstant	=	1000;		// 一次读取串口数据的固定超时。所以在一次读取串口的操作中,其超时为ReadTotalTimeoutMultiplier乘以读取的字节数再加上 ReadTotalTimeoutConstant。
															//  将ReadIntervalTimeout设置为MAXDWORD,并将ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant设置为0,表示读取操作将立即返回存放在输入缓冲区的字符。
	// CBR_9600 is approximately 1byte/ms. For our purposes, allow
    // double the expected time per character for a fudge factor.
	commtimeouts.WriteTotalTimeoutMultiplier=	2*CBR_9600/m_dwBaudRate;
															// 写入每字符间的超时。
	commtimeouts.WriteTotalTimeoutConstant	=	0;			// 一次写入串口数据的固定超时。所以在一次写入串口的操作中,其超时为WriteTotalTimeoutMultiplier乘以写入的字节数再加上WriteTotalTimeoutConstant。
	SetCommTimeouts(m_hComm, &commtimeouts);

	DCB dcb;
	dcb.DCBlength		=	sizeof(DCB);
	GetCommState(m_hComm, &dcb);
	dcb.BaudRate		=	CBR_9600;
	dcb.ByteSize		=	8;
	dcb.Parity			=	NOPARITY;
	dcb.StopBits		=	ONESTOPBIT;

	dcb.fBinary			=	FALSE;
	dcb.fDsrSensitivity	=	FALSE;
	dcb.fOutxCtsFlow	=	FALSE;
	dcb.fOutxDsrFlow	=	FALSE;
	dcb.fOutX			=	FALSE;
	dcb.fInX			=	FALSE;
	dcb.fDtrControl		=	DTR_CONTROL_DISABLE; 
	dcb.fRtsControl		=	DTR_CONTROL_DISABLE; 
	dcb.fInX=dcb.fOutX	=	FALSE; 
	dcb.fParity			=	TRUE;
	dcb.fAbortOnError	=	TRUE;

	dcb.XonChar			=	0x11;
	dcb.XoffChar		=	0x13;
	dcb.XonLim			=	100 ;
	dcb.XoffLim			=	100 ;

	SetCommState(m_hComm, &dcb);
}

void CSerialPort::Close()
{
	if(m_hComm == INVALID_HANDLE_VALUE)
		return;

	SetCommMask(m_hComm, 0);
	// Purge any outstanding reads/writes and close device handle.
	PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
	CloseHandle(m_hComm);
	m_hComm = INVALID_HANDLE_VALUE;
}

BOOL CSerialPort::IsOpen() const
{
	return (m_hComm != INVALID_HANDLE_VALUE);
}

BOOL CSerialPort::Write(BYTE* pBuffer, DWORD dwLength)
{
	if(m_hComm == INVALID_HANDLE_VALUE)
		return FALSE;

	PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
	DWORD dwBytesWritten;
	if(!WriteFile(m_hComm, pBuffer, dwLength, &dwBytesWritten, NULL))
	{
		DWORD dwErrors;
		COMSTAT comstat;
		PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
		ClearCommError(m_hComm, &dwErrors, &comstat);
		return FALSE;
	}

	return TRUE;
}

BOOL CSerialPort::Read(BYTE* pBuffer, DWORD dwLength)
{
	if(m_hComm == INVALID_HANDLE_VALUE)
		return FALSE;

	DWORD dwBytesRead;
	DWORD dwErrors;
	COMSTAT constat;
	ClearCommError(m_hComm, &dwErrors, &constat);
	SetRTS();
	if(!ReadFile(m_hComm, pBuffer, dwLength, &dwBytesRead, NULL))
	{
		PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
		ClearCommError(m_hComm, &dwErrors, &constat);
		ClearRTS();
		return FALSE;
	}
	ClearRTS();

	return TRUE;
}

void CSerialPort::SetBaudRate(DWORD dwBaudRate)
{
	if(m_hComm == INVALID_HANDLE_VALUE)
		return;
	if(m_dwBaudRate == dwBaudRate)
		return;

	DCB dcb;
	dcb.DCBlength	=	sizeof(DCB);
	GetCommState(m_hComm, &dcb);
	dcb.BaudRate	=	dwBaudRate;
	SetCommState(m_hComm, &dcb);

	m_dwBaudRate	=	dwBaudRate;
}

void CSerialPort::SetParity(BYTE byParity)
{
	if(m_hComm == INVALID_HANDLE_VALUE)
		return;

	DCB dcb;
	dcb.DCBlength		=	sizeof(DCB);
	GetCommState(m_hComm, &dcb);
	dcb.Parity			=	byParity;
	SetCommState(m_hComm, &dcb);
}

void CSerialPort::SetRTS()
{
	EscapeCommFunction(m_hComm, SETRTS);
}

void CSerialPort::ClearRTS()
{
	EscapeCommFunction(m_hComm, CLRRTS);
}

⌨️ 快捷键说明

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