C++实现上位机5:实现串口控制类之派生类CSerialPort实现2

111

#include "CSerialPort.h"
//#include "../stdafx.h"
#include "../Tool/CRC.h"
#include 
CSerialPort::CSerialPort() :m_hCom(NULL), m_strCOM(L""){

}

CSerialPort::~CSerialPort(){
#ifdef __AFX_H__  
	return;
#else//如果是MFC程序就不需要自己的释放m_hCOM
	if (m_hCom != NULL){
		CloseHandle(m_hCom);
	}
#endif 
}

/**************************************************************************************/

#ifdef __AFX_H__ 
void CSerialPort::SetPort(CString COM){
	m_strCOM = COM;
}
#else
void CSerialPort::SetMyPort(std::wstring COM){
	m_strCOM = COM;
}
#endif 

int CSerialPort::SetDCB(DWORD BaudRate, BYTE ByteSize, BYTE Parity, BYTE StopBits){
	GetCommState(m_hCom, &m_wdcb);
	m_wdcb.BaudRate = BaudRate;//波特率:57600,其他:不变  
	m_wdcb.ByteSize = ByteSize;   //每个字节8位  
	m_wdcb.Parity = Parity;  //无校验
	m_wdcb.StopBits = StopBits;//1位停止位
	return SetCommState(m_hCom, &m_wdcb);;
}

int CSerialPort::SetCache(DWORD InBuff, DWORD OutBuff){
	return SetupComm(m_hCom, InBuff, OutBuff); //输入缓冲区和输出缓冲区的大小都是1024
}

int CSerialPort::SetTimeout(COMMTIMEOUTS timeOuts){
	m_TimeOuts = timeOuts;
	return SetCommTimeouts(m_hCom, &m_TimeOuts); //设置超时  
}

/**************************************************************************************/

void CSerialPort::CloseHcom(){
	if (m_hCom != NULL){
		CloseHandle(m_hCom);
	}
}

bool CSerialPort::OpenSerialPort(){
	m_hCom = CreateFile(m_strCOM.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

	if (m_hCom == INVALID_HANDLE_VALUE)
	{
		PrintMessage("打开COM失败");
		return false;
	}
	else
	{
		memset(&m_TimeOuts, 0, sizeof(m_TimeOuts));
		m_TimeOuts.ReadIntervalTimeout = 1;
		//如果ReadIntervalTimeout为0,则该值不起作用。
		m_TimeOuts.ReadTotalTimeoutMultiplier = 1;
		m_TimeOuts.ReadTotalTimeoutConstant = 10;
		/*如果值为MAXDWORD,
		并且ReadTotalTimeoutConstant和ReadTotalTimeoutMultiplier两个值都为0,
		则指定读操作携带已经收到的字符立即返回,即使没有收到任何字符。*/
		//设定写超时  
		m_TimeOuts.WriteTotalTimeoutMultiplier = 50;
		m_TimeOuts.WriteTotalTimeoutConstant = 2000;

		/*如果   WriteTotalTimeoutMultiplier   和   WriteTotalTimeoutConstant都为0,则在写操作时忽略总超时数。
		提示:用户设置通讯超时后,如没有出错,串口已经被打开。*/

		if (!SetCommTimeouts(m_hCom, &m_TimeOuts)){//设置超时 
			PrintMessage("设置超时失败!(set timeout failed)");
			CloseHandle(m_hCom);
			return false;
		}

		if (!SetupComm(m_hCom, 1024, 1024)){ //输入缓冲区和输出缓冲区的大小都是1024  
			PrintMessage("设置缓存区失败!(set cache failed)");
			CloseHandle(m_hCom);
			return false;
		}

		if (!GetCommState(m_hCom, &m_wdcb)){
			PrintMessage("获取通讯状态字失败!(get ComState failed)");
			CloseHandle(m_hCom);
			return false;
		}
		m_wdcb.BaudRate = 57600;//波特率:57600,其他:不变  
		m_wdcb.ByteSize = 8;   //每个字节8位  
		m_wdcb.Parity = NOPARITY;  //无校验
		m_wdcb.StopBits = ONESTOPBIT;//1位停止位
		if (!SetCommState(m_hCom, &m_wdcb)){
			PrintMessage("设置通讯状态字失败!(set ComState failed)");
			CloseHandle(m_hCom);
			return false;
		}

		PurgeComm(m_hCom, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR);
	}
	return true;
}

/**************************************************************************************/

bool CSerialPort::Connect(){
	if (m_hCom == NULL){
		return OpenSerialPort();
	}
	else{
		PrintMessage("已经建立连接");
	}
	return false;
}

bool CSerialPort::Connect(std::string com){
	if (m_hCom == NULL){
		SetMyPort(Ansi2WChar(com.c_str(), com.size()));
		return OpenSerialPort();
	}
	else{
		PrintMessage("已经建立连接");
	}
	return false;
}

bool CSerialPort::Disconnect(){
	if (m_hCom != NULL){
		CloseHcom();
		return true;
	}
	else{
		PrintMessage("并没有连接");
	}
	return false;
}

DWORD CSerialPort::SendData(void* data, DWORD size){
	DWORD wCount;
	if (ClearCommError(m_hCom, &dwError, NULL))
	{
		PurgeComm(m_hCom, PURGE_TXABORT | PURGE_TXCLEAR);
	}

	if (!WriteFile(m_hCom, data, size, &wCount, NULL)){
		dwError = GetLastError();
		//std::cerr << "错误码:" << dwError << std::endl;
		std::stringstream stream;
		stream << dwError;
		std::string strC = "SystemErrorNum:" + stream.str();
		PrintMessage(strC);
		return -1;
	}

	return wCount;//发送数据  
}

char* CSerialPort::ReadData(DWORD& wCount){
	if (ClearCommError(m_hCom, &dwError, NULL))
	{
		PurgeComm(m_hCom, PURGE_RXABORT | PURGE_RXCLEAR);
	}

	if (!ReadFile(m_hCom, m_resver_str, 1023, &wCount, NULL)){
		dwError = GetLastError();
		//std::cerr << "错误码:" << dwError << std::endl;
		std::stringstream stream;
		stream << dwError;
		std::string strC = "SystemErrorNum:" + stream.str();
		PrintMessage(strC);
		return NULL;
	}
	return m_resver_str;
}

std::wstring CSerialPort::Ansi2WChar(LPCSTR pszSrc, int nLen)

{
	int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
	if (nSize <= 0) return NULL;

	WCHAR *pwszDst = new WCHAR[nSize + 1];
	if (NULL == pwszDst) return NULL;

	MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, pwszDst, nSize);
	pwszDst[nSize] = 0;

	if (pwszDst[0] == 0xFEFF) // skip Oxfeff  
	for (int i = 0; i < nSize; i++)
		pwszDst[i] = pwszDst[i + 1];

	std::wstring wcharString(pwszDst);
	delete pwszDst;

	return wcharString;
}

bool CSerialPort::IsConnect(){
	if (m_hCom != NULL){
		return true;
	}
	else{
		return false;
	}
}

222

你可能感兴趣的:(Visual,C++开发,Visual,C++开发)