windows串口通信CreateFile

这里写自定义目录标题

头文件

#pragma once
#ifndef XWSERIAL_H

#define XWSERIAL_H

#include <iostream>
using namespace std;

class cSerialClass
{
public:
	cSerialClass();
	~cSerialClass();
	int open(const char *portname, int bortrate = 115200, char parity = 0, char databit = 8, char stopbit = 1, char synFlag = 1);
	void close();

	int send(string dat);

	string receive();
private:
	int pHandle[16];
	char synFlag;
};

#endif

#源文件

#include "xwSerial.h"
#include <stdio.h>
#include <string.h>
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
using namespace std;

cSerialClass::cSerialClass() {}

cSerialClass::~cSerialClass() {}

int cSerialClass::open(const char *portname,
	int bortrate,
	char parity,
	char databit,
	char stopbit,
	char synFlag)
{
	this->synFlag = synFlag;
	HANDLE hCom = NULL;
	if (this->synFlag)
	{
		// 同步类型串口
		hCom = CreateFileA(portname, GENERIC_READ | GENERIC_WRITE, // 可读可写
			0, // 独占方式,不支持共享
			NULL,
			OPEN_EXISTING, // 打开现有的串口文件
			0,  // 同步方式
			NULL
		);
	}
	else
	{
		// 异步串口
		hCom = CreateFileA(portname, GENERIC_READ | GENERIC_WRITE, // 可读可写
			0, // 独占方式,不支持共享
			NULL,
			OPEN_EXISTING, // 打开现有的串口文件
			FILE_FLAG_OVERLAPPED, // 异步方式
			NULL
		);
	}

	if (hCom == (HANDLE)-1)
	{
		return -1;
	}

	if (!SetupComm(hCom, 1024, 1024))
	{
		return -2;
	}

	DCB p;
	memset(&p, 0, sizeof(DCB));
	p.DCBlength = sizeof(p);
	p.BaudRate = bortrate;
	p.ByteSize = databit;

	switch (parity)
	{
	case 0:
		p.Parity = NOPARITY;
		break;
	case 1:
		p.Parity = ODDPARITY;
		break;
	case 2:
		p.Parity = EVENPARITY;
		break;
	case 3:
		p.Parity = MARKPARITY;
		break;
	default:
		break;
	}

	switch (stopbit)
	{
	case 1:
		p.StopBits = ONESTOPBIT;
		break;
	case 2:
		p.StopBits = TWOSTOPBITS;
		break;
	case 3:
		p.StopBits = ONE5STOPBITS;
		break;
	default:
		break;
	}

	if (!SetCommState(hCom, &p))
	{
		// 设置参数失败
		return -3;
	}

	// 超时处理 
	COMMTIMEOUTS timeOuts;
	timeOuts.ReadIntervalTimeout = 1000;
	timeOuts.ReadTotalTimeoutMultiplier = 5000;
	timeOuts.ReadTotalTimeoutConstant = 5000;
	timeOuts.WriteTotalTimeoutMultiplier = 500;
	timeOuts.WriteTotalTimeoutConstant = 2000;

	SetCommTimeouts(hCom, &timeOuts);

	PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);

	memcpy(pHandle, &hCom, sizeof(hCom));

	return 0;
}

void cSerialClass::close()
{
	HANDLE hCom = *(HANDLE*)pHandle;
	CloseHandle(hCom);
}

int cSerialClass::send(string dat)
{
	HANDLE hCom = *(HANDLE*)pHandle;
	if (this->synFlag)
	{
		DWORD dwByteWrite = dat.length();
		BOOL bWriteStat = WriteFile(hCom,
			(char*)dat.c_str(),
			dwByteWrite,
			&dwByteWrite,
			NULL);
		if (!bWriteStat) return 0;
		return dwByteWrite;
	}
	else
	{
		DWORD dwByteWrite = dat.length();
		DWORD dwErrorFlags;
		COMSTAT comStat; // 通讯状态
		OVERLAPPED m_osWrite; // 异步输入输出结构体

		memset(&m_osWrite, 0, sizeof(m_osWrite));
		m_osWrite.hEvent = CreateEventA(NULL, TRUE, FALSE, "Write Event 111");

		ClearCommError(hCom, &dwErrorFlags, &comStat);

		BOOL bWriteStat = WriteFile(hCom,
			(char*)dat.c_str(),
			dwByteWrite,
			&dwByteWrite,
			&m_osWrite);
		if (!bWriteStat)
		{
			if (GetLastError() == ERROR_IO_PENDING) // 串口正在写入
			{
				WaitForSingleObject(m_osWrite.hEvent, 1000);
			}
			else
			{
				ClearCommError(hCom, &dwErrorFlags, &comStat);
				CloseHandle(m_osWrite.hEvent);
				return 0;
			}
		}
		return dwByteWrite;
	}
}

string cSerialClass::receive()
{
	HANDLE hCom = *(HANDLE*)pHandle;
	string rec_str = "";
	char buf[1024];
	if (this->synFlag)
	{
		DWORD wCount = 1024;
		BOOL bReadStat = ReadFile(hCom,
			buf,
			wCount,
			&wCount,
			NULL);
		for (int i = 0; i < 1024; i++)
		{
			if (buf[i] != -52)
			{
				rec_str += buf[i];
			}
			else
				break;
		}
		rec_str = buf;
		return rec_str;
	}
	else
	{
		DWORD wCount = 1024;
		DWORD dwErrorFlags;
		COMSTAT comStat; // 通讯状态
		OVERLAPPED m_osRead; // 异步输入输出结构体

		memset(&m_osRead, 0, sizeof(m_osRead));
		m_osRead.hEvent = CreateEventA(NULL, TRUE, FALSE, "Read Event 222");

		ClearCommError(hCom, &dwErrorFlags, &comStat);
		if (!comStat.cbInQue) return 0;

		BOOL bReadStat = ReadFile(hCom,
			buf,
			wCount,
			&wCount,
			&m_osRead);
		if (!bReadStat)
		{
			if (GetLastError() == ERROR_IO_PENDING) // 串口正在写入
			{
				WaitForSingleObject(m_osRead.hEvent, 1000);
			}
			else
			{
				ClearCommError(hCom, &dwErrorFlags, &comStat);
				CloseHandle(m_osRead.hEvent);
				return 0;
			}
		}
		/*for (int i = 0; i < 1024; i++)
		{
			if (buf[i] != -52)
			{
				rec_str += buf[i];
			}
			else
				break;
		}*/
		rec_str = buf;
		return rec_str;
	}
}

##需要注意的点:
com端口<10的时候,可以直接用"COMX",大于10的时候,需要用"\\.\COMX"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值