首页 > 代码库 > 上位机简单串口类,VC串口类

上位机简单串口类,VC串口类

我是在一家做硬件的的公司里面做软件开发工程师的,我做的软件大多是是编写软件通过串口去控制硬件,所以串口编程对于我来说是很重要的。串口编程之前一直使用的是自己写的简单串口(只有发送,没有接收)类,或者上网下的CSerialPort类(个人觉得不好用啊,互锁变量一堆,代码一开始还让人看不懂,对于上位机使用不合适)。对于我做的上位机软件,其实使用串口只是需要顺序发送,接收数据无误就行了,不需要考虑太多东西。所以最近有点空,就自己再写了一个串口类(希望可以简单使用的,没有太高的要求的)。

(1)界面

界面是粗糙了点,随便显示数据而已。

(2)代码

①代码文件列表

通过继承和多态让串口相关的类可以随意替换,另外上面那个“串口管理委托"类,其实是参照Object-C的委托,觉得很好,自己也一直使用这种设计模式

②代码介绍

串口管理类:主要给主窗口调用,逻辑分层:主窗口-串口管理-串口类

#pragma once

#include "BaseComManage.h"

class CBaseCom;

class CComManage : public CBaseComManage
{
public:
	CComManage(void);
	~CComManage(void);

	//初始化
	virtual void Init();

	//获取串口状态
	virtual BOOL GetComState();

	//打开串口
	virtual BOOL OpenCom(CString szComName, CString szBaudRate, 
		CString szByteSize, CString szParity, CString szStopBits);

	//关闭串口
	virtual void CloseCom();

	//发送串口数据
	virtual BOOL SendData(const char* pData, const int nLen);

	//添加串口名称到ComboBox
	virtual void AddComNameToComboBox(CComboBox* pComBox);

	//添加波特率到ComboBox
	virtual void AddBaudRateToComboBox(CComboBox* pComBox);

	//添加数据位到ComboBox
	virtual void AddByteSizeToComboBox(CComboBox* pComBox);

	//添加停止位到ComboBox
	virtual void AddStopBitToComboBox(CComboBox* pComBox);

	//添加检验位到ComboBox
	virtual void AddParityToComboBox(CComboBox* pComBox);

private:

	//获取检验位
	BYTE GetParity(CString szData);

	//获取停止位
	BYTE GetStopBit(CString szData);

	//获取数据位
	BYTE GetByteSize(CString szData);

	//获取波特率
	DWORD GetBaudRate(CString szData);

	//获取串口名称
	CString GetComName(CString szComName);

private:

	//串口
	CBaseCom* m_pCom;
};
#include "StdAfx.h"
#include "ComManage.h"
#include "DelegateComManage.h"
#include "XCom.h"

CComManage::CComManage(void)
{
	m_pCom = nullptr;
}


CComManage::~CComManage(void)
{
	if (nullptr != m_pCom)
	{
		delete m_pCom;

		m_pCom = nullptr;
	}
}

/***********************************************************
** 功能描述: 初始化
************************************************************/
void CComManage::Init()
{
	m_pCom = new XCom;
}

/***********************************************************
** 功能描述: 获取串口状态
************************************************************/
BOOL CComManage::GetComState()
{
	return m_pCom->GetComState();
}

/***********************************************************
** 功能描述: 打开串口
************************************************************/
BOOL CComManage::OpenCom(CString szComName, CString szBaudRate, 
	CString szByteSize, CString szParity, CString szStopBits)
{
	return m_pCom->OpenCom(m_pDelegate->GetHWND(), GetComName(szComName), 
		GetBaudRate(szBaudRate), GetParity(szParity), GetByteSize(szByteSize), GetStopBit(szStopBits));
}

/***********************************************************
** 功能描述: 关闭串口
************************************************************/
void CComManage::CloseCom()
{
	m_pCom->CloseCom();
}

/***********************************************************
** 功能描述: 发送串口数据
************************************************************/
BOOL CComManage::SendData(const char* pData, const int nLen)
{
	return m_pCom->SendData(pData, nLen);
}

/***********************************************************
** 功能描述: 添加串口名称到ComboBox
************************************************************/
void CComManage::AddComNameToComboBox(CComboBox* pComBox)
{
	if (nullptr != pComBox)
	{
		pComBox->ResetContent();

		HKEY hKey;  

		//打开串口注册表
		LONG nResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Hardware\\DeviceMap\\SerialComm"), 
			NULL, KEY_READ, &hKey);

		if (ERROR_SUCCESS == nResult)     
		{
			DWORD dwPortName = MAX_PATH;
			DWORD dwComName = MAX_PATH;

			TCHAR cPortName[MAX_PATH];
			TCHAR cComName[MAX_PATH];  

			DWORD dwIndex = 0;

			CString szTemp = _T("");

			while(1)   
			{
				ZeroMemory(cPortName, MAX_PATH);
				ZeroMemory(cComName, MAX_PATH);

				dwPortName = MAX_PATH;
				dwComName = MAX_PATH;

				if (::RegEnumValue(hKey, dwIndex, cPortName, &dwPortName, NULL, NULL, (LPBYTE)cComName, 
					&dwComName) == ERROR_NO_MORE_ITEMS)
				{
					break;
				}

				szTemp.Format(_T("%s"), cComName);

				pComBox->AddString(cComName);

				dwIndex++;
			}

			RegCloseKey(hKey);
		}
	}
}

/***********************************************************
** 功能描述: 添加波特率到ComboBox
************************************************************/
void CComManage::AddBaudRateToComboBox(CComboBox* pComBox)
{
	if (nullptr != pComBox)
	{
		pComBox->ResetContent();

		pComBox->AddString(_T("2400"));
		pComBox->AddString(_T("4800"));
		pComBox->AddString(_T("9600"));
		pComBox->AddString(_T("14400"));
		pComBox->AddString(_T("19200"));
		pComBox->AddString(_T("38400"));
		pComBox->AddString(_T("57600"));
		pComBox->AddString(_T("115200"));
		pComBox->AddString(_T("128000"));
		pComBox->AddString(_T("256000"));
	}
}

/***********************************************************
** 功能描述: 添加数据位到ComboBox
************************************************************/
void CComManage::AddByteSizeToComboBox(CComboBox* pComBox)
{
	if (nullptr != pComBox)
	{
		pComBox->ResetContent();

		pComBox->AddString(_T("4"));
		pComBox->AddString(_T("5"));
		pComBox->AddString(_T("6"));
		pComBox->AddString(_T("7"));
		pComBox->AddString(_T("8"));
	}
}

/***********************************************************
** 功能描述: 添加停止位到ComboBox
************************************************************/
void CComManage::AddStopBitToComboBox(CComboBox* pComBox)
{
	if (nullptr != pComBox)
	{
		pComBox->ResetContent();

		pComBox->AddString(_T("1"));
		pComBox->AddString(_T("1.5"));
		pComBox->AddString(_T("2"));
	}
}

/***********************************************************
** 功能描述: 添加检验位到ComboBox
************************************************************/
void CComManage::AddParityToComboBox(CComboBox* pComBox)
{
	if (nullptr != pComBox)
	{
		pComBox->ResetContent();

		pComBox->AddString(_T("NO"));
		pComBox->AddString(_T("ODD"));
		pComBox->AddString(_T("EVEN"));
		pComBox->AddString(_T("MARK"));
	}
}

/***********************************************************
** 功能描述: 获取检验位
************************************************************/
BYTE CComManage::GetParity(CString szData)
{
	BYTE cData = http://www.mamicode.com/0;>
串口类:

#pragma once

#include "BaseCom.h"

class XCom : public CBaseCom
{
public:
	XCom(void);
	~XCom(void);

	//打开串口
	virtual BOOL OpenCom(HWND pPortOwner, CString szComName, 
		DWORD nBaudRate, BYTE cParity, BYTE nByteSize, BYTE cStopsBits);

	//获取串口状态
	virtual BOOL GetComState();

	//关闭串口
	virtual void CloseCom();

	//发送串口数据
	virtual BOOL SendData(const char* pData, const int nLen);
	
public:

	//串口线程函数
	static UINT ComThread(LPVOID pParam);

	//接收字符
	BOOL ReceiveChar(DWORD dwLen);

private:

	//打开串口
	BOOL OpenCom(CString szComName);

	//设置DCB
	BOOL SetDCB(DWORD nBaudRate, BYTE cParity, BYTE nByteSize, 
		BYTE cStopsBits);

	//开始监控
	void StartMonitoring();

	//停止监控
	void StopMonitoring();

public:

	//串口句柄
	HANDLE m_hComm;

	//线程结束事件句柄
	HANDLE m_hThreadEndEvent; 

	//窗口句柄
	HWND m_Owner;

private:

	//串口状态
	BOOL m_bComSate;

	//串口DCB
	DCB	m_dcb;
};

#include "StdAfx.h"
#include "XCom.h"
#include "Constant.h"

XCom::XCom(void)
{
	m_bComSate = FALSE;

	m_Owner = NULL;

	m_hComm = INVALID_HANDLE_VALUE;

	m_hThreadEndEvent = NULL;
}


XCom::~XCom(void)
{
	CloseCom();
}

/***********************************************************
** 功能描述: 打开串口
************************************************************/
BOOL XCom::OpenCom(HWND pPortOwner, CString szComName, 
	DWORD nBaudRate, BYTE cParity, BYTE nByteSize, BYTE cStopsBits)
{
	if (OpenCom(szComName))
	{
		if (SetDCB(nBaudRate, cParity, nByteSize, cStopsBits))
		{
			if (SetCommMask(m_hComm, EV_RXCHAR))
			{
				if(PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR 
					| PURGE_RXABORT | PURGE_TXABORT))
				{
					StartMonitoring();

					m_Owner = pPortOwner;

					m_bComSate  = TRUE;
				}
			}
		}
	}

	if (!m_bComSate)
	{
		CloseCom();
	}

	return m_bComSate;
}

/***********************************************************
** 功能描述: 设置DCB
************************************************************/
BOOL XCom::SetDCB(DWORD nBaudRate, BYTE cParity, BYTE nByteSize, 
	BYTE cStopsBits)
{
	if (!GetCommState(m_hComm, &m_dcb))
	{
		return FALSE;
	}

	m_dcb.BaudRate = nBaudRate; 
	m_dcb.Parity   = cParity;
	m_dcb.ByteSize = nByteSize;
	m_dcb.StopBits = cStopsBits;

	return SetCommState(m_hComm, &m_dcb);
}

/***********************************************************
** 功能描述: 获取串口状态
************************************************************/
BOOL XCom::GetComState()
{
	return m_bComSate;
}

/***********************************************************
** 功能描述: 关闭串口
************************************************************/
void XCom::CloseCom()
{
	m_bComSate  = FALSE;

	if (INVALID_HANDLE_VALUE != m_hComm)
	{
		CloseHandle(m_hComm);

		m_hComm = INVALID_HANDLE_VALUE;
	}

	StopMonitoring();
}

/***********************************************************
** 功能描述: 打开串口
************************************************************/
BOOL XCom::OpenCom(CString szComName)
{
	m_hComm = CreateFile(szComName, GENERIC_READ | GENERIC_WRITE, 0, NULL,							
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, 0);								

	if (INVALID_HANDLE_VALUE =http://www.mamicode.com/= m_hComm)>
串口是用异步模式创建的,但使用是拿来当同步使用,是不是有大材小用,傻X是不,其实本是是想写成异步的,便同步比较好做,简单,就搞成四不像吧,方便进化成彻底异步模式。串品有数据到来时是用new一个char数组进行保存,然后发消息到主窗口,所以分配和释放内存这么多次不知道好不好,但如果只用一个共用的char数组进行保存时,就要使用互斥变量,处理慢。

(3)感想

我知道写得并不是很好,但足够我自己用了,试过没有问题,所以放上来给大家看看,供参考.


源码地址:http://pan.baidu.com/share/link?shareid=3711001912&uk=2852477476


上位机简单串口类,VC串口类