通过串口类CSerial实现串口功能

  • Post author:
  • Post category:其他


1、SerialComm.h成员变量,成员函数声明

#pragma once

#define    WM_COMM_RX    0x0400 + 500     //串口消息接收信号宏定义
#define    REV_LEN       1000             //接收的字节数
class CSerialComm
{
public:
	CSerialComm();
	~CSerialComm();
public:
	BOOL OpenComm(LPCTSTR lpFileName);
	void SetCommStat(DCB mDcbComm);
	BOOL GetCommStat(DCB* mDcbComm);
	BOOL ReadFileStat();
	BOOL WriteFileStat(char *p, UINT len);
	BOOL CloseHandleStat();
	//读取线程,读取串口数据
	static unsigned int __stdcall OnRecv(void*);
	void CreateRecvThread();     //创建读取数据线程
private:
	BOOL m_nWorkIng;
	

public:
	CWinThread* m_pThread;  //线程指针
	COMMTIMEOUTS  m_nTimeout;
	DCB m_nDcb;
	HANDLE m_hComm;
	CString m_nOutputContext;
	char m_nInputContext[1000];
	CString m_revData;
	DWORD m_nReceiveNum;
	HWND m_hWnd;
};

2、打开串口


BOOL CSerialComm::OpenComm(LPCTSTR lpFileName)
{
	m_hComm = CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, 0, NULL);
	
    	if (m_hComm == INVALID_HANDLE_VALUE)
		{
			AfxMessageBox("打开串口失败!");
			return FALSE;
		}	
			return TRUE;		
}

3、设置串口参数


void CSerialComm::SetCommStat(DCB mDcbComm)
{
	
	COMMTIMEOUTS TimeOuts;   //设定超时时间
	TimeOuts.ReadIntervalTimeout = 1000;
	TimeOuts.ReadTotalTimeoutMultiplier = 500;
	TimeOuts.ReadTotalTimeoutConstant = 5000; //设定写超时
	TimeOuts.WriteTotalTimeoutMultiplier = 100;
	TimeOuts.WriteTotalTimeoutConstant = 500;
	SetCommTimeouts(m_hComm, &TimeOuts);
	SetupComm(m_hComm, 1024, 1024);
	

	if (!SetCommState(m_hComm, &mDcbComm))
	{
		AfxMessageBox("串口设置失败!");
		return;
	}
	PurgeComm(m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR);
	
}

4、读取串口数据


//异步读取串口数据
BOOL CSerialComm::ReadFileStat()
{
	DWORD dwBytesWrite = 1000;
	DWORD wCount;
	BOOL bReadStatus;
	DWORD dwErrorFlags;
	COMSTAT ComStat;
	OVERLAPPED m_osRead;
	ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
	bReadStatus = ReadFile(m_hComm, m_nInputContext, 1000, &wCount, NULL);
	if (!bReadStatus)
	{
			AfxMessageBox("读串口失败!");
			return FALSE;
	}
	PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
	m_nReceiveNum = wCount;
	return TRUE;
}

5、创建线程,循环等待接收串口数据


//循环等待串口数据
unsigned int __stdcall CSerialComm::OnRecv(void* LPParam)//接收数据
{
	CSerialComm *obj = static_cast<CSerialComm*>(LPParam);
	CString revData;
	UINT len = REV_LEN;
	while (true)
	{
		obj->ReadFileStat();
		revData = obj->m_nInputContext;
		obj->m_revData = revData;
		::PostMessage(obj->m_hWnd, WM_COMM_RX, (WPARAM)(CString *)&obj->m_revData, (LPARAM)(UINT)len);
	}
	return 0;
}

//创建消息接收线程
void CSerialComm::CreateRecvThread()
{
	(HANDLE)_beginthreadex(NULL, 0, &CSerialComm::OnRecv, this, 0, NULL);
}

6、串口初始化操作

如果在其他类中使用该串口类,需要创建一个串口对象,具体的串口初始化如下:

CSerialComm *serialComm = new CSerialComm();
initSerial()
{
	CString serialnum, sbaudrate;
	UINT nbaudrate;
	serialnum = "COM5";
	sbaudrate = "9600";
	nbaudrate = _tstoi(sbaudrate);
	DCB dcb;
	serialComm->OpenComm(serialnum);
	serialComm->GetCommStat(&dcb);
	//设置串口参数
	dcb.BaudRate = nbaudrate;
	dcb.ByteSize = 8;
	dcb.Parity = NOPARITY;
	dcb.StopBits = ONESTOPBIT;
	serialComm->SetCommStat(dcb);
	serialComm->CreateRecvThread();
	serialComm->m_hWnd = m_hWnd;
}

7、下面是我写的一个串口下例子,可以参考一些

下面是完整代码,需要的可以下载


https://download.csdn.net/download/csdn_zyp2015/10787370



版权声明:本文为csdn_zyp2015原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。