MFC串口操作函数

最近在看串口助手程序的源码,这里把串口调用相关函数分享一下

SerialPort.cpp文件

#include "SerialPort.h"

SerialPort::SerialPort(
	const porttype& portNum, 
	DWORD baudRate /* = 9600 */, 
	BYTE byteSize /* = 8 */, 
	BYTE parityBit /* = NOPARITY */, 
	BYTE stopBit /* = ONESTOPBIT */): 
	m_portNum(portNum), 
	m_dwBaudRate(baudRate), 
	m_byteSize(byteSize), 
	m_parityBit(parityBit), 
	m_stopBit(stopBit), 
	m_bOpen(false) 
	{ 
		;
	}
SerialPort::~SerialPort()
{ 
	;
} 

// 打开串口成功,返回 true 
bool SerialPort::openComm()
{
#ifdef _UNICODE	
	m_hComm = CreateFile(
		m_portNum,
		GENERIC_READ | GENERIC_WRITE, //允许读和写		
		0,		//独占方式		
		NULL, 
		OPEN_EXISTING,   //打开而不是创建		
		0,   //同步方式		
		NULL
	);
#else	
	m_hComm = CreateFileA(m_portNum.c_str(),
		GENERIC_READ | GENERIC_WRITE, //允许读和写
		0,		//独占方式		
		NULL, OPEN_EXISTING,   //打开而不是创建		
		0,   //同步方式		
		NULL		
	);
#endif 	
	if (m_hComm == INVALID_HANDLE_VALUE)
	{
#ifdef _UNICODE		
		TCHAR szBuf[1024] = { 0 };	
		wsprintf(szBuf, L"打开 %s 失败,代码: %d",
		m_portNum, GetLastError());	
		MessageBox(NULL, szBuf, L"Warnning", MB_OK);
#else
		char szBuf[1024] = { 0 };
		sprintf_s(szBuf, "打开 %s 失败,代码: %d", m_portNum.c_str(),GetLastError());
		MessageBox(NULL, szBuf, "Warnning", MB_OK);
#endif // _UNICODE 		
		return false; 	
	}
	else
	{
		COMMTIMEOUTS timeOuts;
		timeOuts.ReadIntervalTimeout = MAXDWORD;
		timeOuts.ReadTotalTimeoutConstant = 0;
		timeOuts.ReadTotalTimeoutMultiplier = 0;
		timeOuts.WriteTotalTimeoutConstant = 100;
		timeOuts.WriteTotalTimeoutMultiplier = 5000;
		SetCommTimeouts(m_hComm,&timeOuts);

		DCB dcb;
		SetupComm(m_hComm, MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);	// 设置读写缓冲区大小	
		GetCommState(m_hComm, &dcb);
		dcb.BaudRate = m_dwBaudRate;
		dcb.ByteSize = m_byteSize;
		dcb.Parity = m_parityBit;
		dcb.StopBits = m_stopBit; 
		if (!SetCommState(m_hComm, &dcb))
		{
#ifdef _UNICODE
			TCHAR szBuf[1024] = { 0 };
			wsprintf(szBuf, L"串口设置失败,错误代码: %d", GetLastError());	
			MessageBox(NULL, szBuf, TEXT("ERROR"), MB_OK);
#else			
			char szBuf[1024] = { 0 };
			wsprintf(szBuf, "串口设置失败,错误代码: %d", GetLastError());
			MessageBox(NULL, szBuf, "ERROR", MB_OK);
#endif
			return false;
		}
	} 	
	//在读写串口前,用 PurgeComm 函数清空缓冲区	
	PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_TXABORT | PURGE_TXABORT);
	m_bOpen = true;
	return true; 
} 

// 关闭串口 
void SerialPort::closeComm()
{
	CloseHandle(m_hComm);
}  

// 向串口发送数据
bool SerialPort::writeToComm(BYTE data[], DWORD dwLength)
{
#ifdef _DEBUG	
	assert(m_bOpen == true || dwLength > 0);
	//return false;
#endif // _DEBUG
	DWORD dwError = 0;
	if (ClearCommError(m_hComm, &dwError, NULL) && dwError > 0)
	{
		PurgeComm(m_hComm, PURGE_TXABORT | PURGE_TXCLEAR);
	}
	DWORD dwTx = 0;
	BOOL ret = FALSE;
	ret = WriteFile(m_hComm, data, dwLength, &dwTx, NULL);
	if (ret == FALSE)
	{
#ifdef _UNICODE	
		TCHAR szBuf[1024] = { 0 };	
		wsprintf(szBuf, _T("读取数据失败,错误代码: %d"), GetLastError());
		MessageBox(NULL, szBuf, L"ERROR", MB_OK);
#else
		char szBuf[1024] = { 0 };
		sprintf_s(szBuf, "读取数据失败, 错误代码: %d", GetLastError());
		MessageBox(NULL, szBuf, "Error", MB_OK);
#endif // _UNICODE 	
		return false;
	} 	
	return true; 
} 

// 从串口中读取数据 
bool SerialPort::readFromComm(BYTE buffer[], DWORD dwLength, DWORD &dwRx)
{
#ifdef _DEBUG	
	assert(m_bOpen == true || dwLength > 0);
	//return false;
#endif // _DEBUG 
	COMSTAT comStat;
	DWORD dwError = 0;
	if (ClearCommError(m_hComm, &dwError, &comStat) && dwError > 0)
	{
		PurgeComm(m_hComm, PURGE_RXABORT | PURGE_RXCLEAR);
	} 
	;	// 读入的字节数
	BOOL ret = FALSE;
	BYTE* byReadData = new BYTE[dwLength];
	char szTmp[4] = { 0 };
	int sizeOfBytes = sizeof(szTmp);
	ret = ReadFile(m_hComm, byReadData, dwLength, &dwRx, NULL);	// 读入数据 
	if (ret == TRUE)
	{
	/*	for (int i = 0; i < dwRx; ++i)
		{
			sprintf_s(szTmp, "%02x", byReadData[i]);
			strcat_s(buffer, sizeOfBytes*dwLength, szTmp);
		} */
		memcpy(buffer,byReadData, dwRx);
		// 释放内存
		if(byReadData)delete[] byReadData;
		return true;
	}
	else
	{
#ifdef _UNICODE	
		TCHAR szBuf[1024] = { 0 };
		wsprintf(szBuf, _T("数据读取失败,错误代码: %d"), GetLastError());
		MessageBox(NULL, szBuf, L"Error", MB_OK);
#else
		char szBuf[1024] = { 0 };
		int ErrorCode = GetLastError();
		wsprintf(szBuf, "数据读取失败,错误代码: %d", ErrorCode);
		MessageBox(NULL, szBuf, "Error", MB_OK);
#endif // _UNICODE
		return false;
	}
	return true;
}

SerialPort.h文件

#pragma once

#include <string>
#include <Windows.h>
#include <cstddef>
#include <cstdlib>
#include <cassert>
#include <iostream>
	// 定义串口类型
#ifdef _UNICODE
	typedef CString porttype;
#else
	typedef std::string porttype;
#endif // _UNICODE 

typedef unsigned long ulong;
typedef unsigned char uchar;

class SerialPort
{
public:	
	SerialPort(
		const porttype & portNum,// 串口号
		DWORD baudRate = 9600,// 波特率
		BYTE  byteSize = 8,// 数据位
		BYTE  parityBit = NOPARITY,// 检验位
		BYTE  stopBit = ONESTOPBIT// 停止位
		);
	~SerialPort();

public:
	bool openComm();// 打开串口
	void closeComm();// 关闭串口
	bool writeToComm(BYTE data[], DWORD dwLegnth);// 发送数据	
	bool readFromComm(BYTE buffer[], DWORD dwLength, DWORD &dwRx);// 读取数据 


private:
	HANDLE m_hComm;// 通信设备
	porttype m_portNum;// 串口号	
	DWORD m_dwBaudRate; // 波特率
	BYTE  m_byteSize;	// 数据位
	BYTE  m_parityBit;  // 校验位
	BYTE  m_stopBit;	// 停止位
	bool  m_bOpen;		// 串口开关标志

private:
	enum BufferSize	{
		MIN_BUFFER_SIZE = 256,
		BUFFER_SIZE = 512,
		MAX_BUFFER_SIZE = 1024
	}; 	
	// 设置串口号
	void setPortNum(const porttype &portNum){this->m_portNum = portNum;}
	// 设置波特率
	void setBaudRate(const ulong baudRate){this->m_dwBaudRate = baudRate;}
	// 设置数据位	
	void setByteSize(const uchar byteSize){this->m_byteSize = byteSize;}
	// 设置检验位
	void setParityBit(const uchar parityBit){this->m_parityBit = parityBit;}
	// 设置停止位
	void setStopBit(const uchar stopBit){this->m_stopBit = stopBit;}
	// 获取串口号
	porttype getPortNum(){return m_portNum;}	
	// 获取波特率
	ulong getBaudRate(){return m_dwBaudRate;}
	// 获取数据位	
	uchar getByteSize(){return m_byteSize;}
	// 获取检验位
	uchar getParityBit(){return m_parityBit;}
	// 获取停止位	
	uchar getStopBit(){return m_stopBit;}

};

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值