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

📄 serialcomm.cpp

📁 一个通用的WINCE下的串口通信类
💻 CPP
字号:
#include "stdafx.h"
#include "serialcomm.h"
#include <string.h>

CSerialComm::CSerialComm()
{
	m_hComm = INVALID_HANDLE_VALUE;
	m_bActive = FALSE;
	m_Error = 0;
	m_OnReceive = NULL;
	m_ReadThread = NULL;
	m_ExecThread = NULL;
}

CSerialComm::~CSerialComm()
{
	Close();
}

BOOL CSerialComm::Open(const int nCom)
{
	if (m_bActive)
	{
		return FALSE;
	}

	TCHAR ComName[7];
	swprintf(ComName, _T("COM%d:"), nCom);
		
	m_hComm = CreateFile(ComName, 
						 GENERIC_READ | GENERIC_WRITE,
						 0,
						 NULL,
						 OPEN_EXISTING,
						 FILE_ATTRIBUTE_NORMAL,
						 NULL);
	if (INVALID_HANDLE_VALUE != m_hComm)
	{
		if (SetupComm(m_hComm, IN_QUEUE_SIZE, OUT_QUEUE_SIZE) && SetTimeOuts() && SetBaud(9600))
		{
			m_bActive = TRUE;
		}
		else
		{
			m_Error = GetLastError();
			CloseHandle(m_hComm);
		}
	}
	else
	{
		m_Error = GetLastError();
	}
	
	return m_bActive;
}

BOOL CSerialComm::IsActive()
{
	return m_bActive;
}

BOOL CSerialComm::SetTimeOuts()
{
	COMMTIMEOUTS TimeOuts;
	//设定读超时
	TimeOuts.ReadIntervalTimeout = MAXDWORD;
	TimeOuts.ReadTotalTimeoutMultiplier = 10;
	TimeOuts.ReadTotalTimeoutConstant = 50;
	//设定写超时
	TimeOuts.WriteTotalTimeoutMultiplier = 10;
	TimeOuts.WriteTotalTimeoutConstant = 50;
	//设置超时
	return SetCommTimeouts(m_hComm, &TimeOuts);
}

BOOL CSerialComm::SetReadTimeOut(DWORD dwTime)
{
	COMMTIMEOUTS TimeOuts;
	if (GetCommTimeouts(m_hComm, &TimeOuts))
	{
		TimeOuts.ReadIntervalTimeout = 500;
		TimeOuts.ReadTotalTimeoutMultiplier = 0;
		TimeOuts.ReadTotalTimeoutConstant = dwTime;
		return SetCommTimeouts(m_hComm, &TimeOuts);
	}

	return FALSE;
}

void CSerialComm::Close()
{
	if (m_bActive)
	{
		CloseHandle(m_hComm);
		m_hComm = INVALID_HANDLE_VALUE;
		m_bActive = FALSE;

		if (m_ReadThread != NULL)
		{
			WaitForSingleObject(m_ReadThread->m_hThread, INFINITE);
			m_ReadThread = NULL;
		}
		if (m_ExecThread != NULL)
		{
			PostThreadMessage(m_ExecThread->m_nThreadID, WM_QUIT, 0, 0);
			WaitForSingleObject(m_ExecThread->m_hThread, INFINITE);
			m_ExecThread = NULL;
		}
	}
}

BOOL CSerialComm::StartAutoRead()
{
	if (!m_bActive || NULL == m_OnReceive || m_ExecThread != NULL)
	{
		return FALSE;
	}

	if ((m_ExecThread = AfxBeginThread(ExecProc, this)) != NULL)
	{
		if (SetEvtMask(EV_RXCHAR)) //EV_RXCHAR  EV_DSR
		{
			m_ReadThread = AfxBeginThread(ReadProc, this);
			return m_ReadThread != NULL;
		}
	}
	
	return FALSE;
}

BOOL CSerialComm::ClearBuffers(DWORD clrFlag)
{
	switch (clrFlag)
	{
	case CLEAR_INBUFFER:
		return PurgeComm(m_hComm, PURGE_RXCLEAR);

	case CLEAR_OUTBUFFER:
		return PurgeComm(m_hComm, PURGE_TXCLEAR);

	case CLEAR_BOTH:
		return PurgeComm(m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR);

	default: return FALSE;
	}
}

BOOL CSerialComm::SetBaud(const int Baud)
{
	if (INVALID_HANDLE_VALUE == m_hComm)
	{
		return FALSE;
	}

	DCB dcb;
	if (GetCommState(m_hComm, &dcb))
	{
		dcb.BaudRate = Baud;		//波特率
		dcb.ByteSize = 8;			//每个字节有8位
		dcb.Parity = NOPARITY;		//无奇偶校验位
		dcb.StopBits = ONESTOPBIT;	//一位停止位
		
		if (SetCommState(m_hComm, &dcb))
		{
			return ClearBuffers(CLEAR_BOTH);
		}
	}

	return FALSE;
}

BOOL CSerialComm::SetEvtMask(DWORD EvtMask)
{
	return SetCommMask(m_hComm, EvtMask);
}

int CSerialComm::GetInBufferLen()
{
	COMSTAT stat;
	DWORD Err = 0;
	if (ClearCommError(m_hComm, &Err, &stat))
	{
		return stat.cbInQue;
	}

	return 0;
}

int CSerialComm::ReadBuf(char *buf, const int BytesToRead)
{
	DWORD BytesRead = 0;
	if (!ReadFile(m_hComm, buf, BytesToRead, &BytesRead, NULL))
	{
		return 0;
	}

	return BytesRead;
}

int CSerialComm::SendBuf(const char *buf, const int BytesToSend)
{
	DWORD BytesSend = 0;
	if (!WriteFile(m_hComm, buf, BytesToSend, &BytesSend, NULL))
	{
		return 0;
	}

	return BytesSend;
}

void CSerialComm::DoOnReceiveData()
{
	PostThreadMessage(m_ExecThread->m_nThreadID, CM_EVENTARRIVE, 0, 0);
}

BOOL CSerialComm::WaitEvent(LPDWORD EvtMask)
{
	return WaitCommEvent(m_hComm, EvtMask, NULL);
}

UINT CSerialComm::ReadProc(LPVOID param)
{
	CSerialComm *pCom = (CSerialComm *)param;

	DWORD EvtMask = 0;
	while (pCom->WaitEvent(&EvtMask))
	{
		pCom->DoOnReceiveData();
	}

	return 0;
}

UINT CSerialComm::ExecProc(LPVOID param)
{
	CSerialComm *pCom = (CSerialComm *)param;
	MSG Msg;

	while (GetMessage(&Msg, NULL, 0, 0))
	{
		if (CM_EVENTARRIVE == Msg.message)
		{
			if (pCom->m_OnReceive != NULL)
			{
				pCom->m_OnReceive(pCom);
			}
		}
	}

	return 0;
}

⌨️ 快捷键说明

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