C 串口类

目录

 

一、参考:

一.自己做

1.Com.h

1.Com.cpp

1.头文件

1.源文件:使用

1.效果

1.注意


一、参考:

https://blog.csdn.net/qq_18984151/article/details/79267005

一.自己做

1.Com.h

#pragma once
#ifndef _com_h_
#define _com_h_
#include <tchar.h>
#include <math.h>
#include<iostream>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>

extern BYTE aaaa[4096];
class ComAsy//定义类
{
public:
	ComAsy();
	~ComAsy();
	bool InitCOM(LPCTSTR Port);//打开串口
	void UninitCOM(); //关闭串口并清理

					  //写入数据
	bool ComWrite(LPBYTE buf, int &len);

	//读取线程
	static unsigned int __stdcall OnRecv(void*);

private:
	HANDLE m_hCom;
	OVERLAPPED m_ovWrite;//用于写入数据
	OVERLAPPED m_ovRead;//用于读取数据
	OVERLAPPED m_ovWait;//用于等待数据
	volatile bool m_IsOpen;//串口是否打开
	HANDLE m_Thread;//读取线程句柄
};
#endif

1.Com.cpp

#include "stdafx.h"
#include"Com.h"


/*************************************串口定义***************************************************/
HANDLE hCom;
unsigned char d[8];
DWORD dwBytesWritten = 9;
DWORD dwErrorFlags = 0;
COMSTAT ComStat;
OVERLAPPED m_osWrite;
BOOL bWriteStat;
bool a;
int i;
int flag = 1;
int serialflag = 0;
int receiveSign;
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
char RXBuff;
BYTE aaaa[4096];


/*****************************************数据定义**************************/



/*****************************************串口类定义**************************/



ComAsy::ComAsy() ://构造函数
	m_hCom(INVALID_HANDLE_VALUE),
	m_IsOpen(false),
	m_Thread(NULL)
{
	memset(&m_ovWait, 0, sizeof(m_ovWait));
	memset(&m_ovWrite, 0, sizeof(m_ovWrite));
	memset(&m_ovRead, 0, sizeof(m_ovRead));
}

ComAsy::~ComAsy()//析构函数
{
	UninitCOM();//串口对象被释放时关闭串口
}


bool ComAsy::InitCOM(LPCTSTR Port)//配置串口
{
	m_hCom = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
		FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL,//设置异步标识
		NULL);
	if (INVALID_HANDLE_VALUE == m_hCom)
	{
		return false;
	}
	SetupComm(m_hCom, 4096, 4096);//设置发送接收缓存

	DCB dcb;//96n81模式
	GetCommState(m_hCom, &dcb);
	dcb.DCBlength = sizeof(dcb);
	dcb.BaudRate = 9600;//波特率
	dcb.StopBits = ONESTOPBIT;//停止位数为1位
	dcb.Parity = 0;//校验方式为无校验
	dcb.ByteSize = 8;//数据位为8位
	SetCommState(m_hCom, &dcb);//配置串口

	PurgeComm(m_hCom, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT);

	COMMTIMEOUTS ct;
	ct.ReadIntervalTimeout = MAXDWORD;//两字符之间最大的延时,读取无延时,因为有WaitCommEvent等待数据
	ct.ReadTotalTimeoutConstant = 0;  //读时间常量
	ct.ReadTotalTimeoutMultiplier = 0;// 读时间系数

	ct.WriteTotalTimeoutMultiplier = 500;// 写时间系数
	ct.WriteTotalTimeoutConstant = 5000;// 写时间常量

	SetCommTimeouts(m_hCom, &ct);//配置读写超时

								 //创建事件对象
	m_ovRead.hEvent = CreateEvent(NULL, false, false, NULL);
	m_ovWrite.hEvent = CreateEvent(NULL, false, false, NULL);
	m_ovWait.hEvent = CreateEvent(NULL, false, false, NULL);

	SetCommMask(m_hCom, EV_ERR | EV_RXCHAR);//设置接受事件

											//创建读取线程
	m_Thread = (HANDLE)_beginthreadex(NULL, 0, &ComAsy::OnRecv, this, 0, NULL);
	m_IsOpen = true;
	return true;
}

void ComAsy::UninitCOM()//关闭串口
{
	m_IsOpen = false;
	if (INVALID_HANDLE_VALUE != m_hCom)
	{
		CloseHandle(m_hCom);
		m_hCom = INVALID_HANDLE_VALUE;
	}
	if (NULL != m_ovRead.hEvent)
	{
		CloseHandle(m_ovRead.hEvent);
		m_ovRead.hEvent = NULL;
	}
	if (NULL != m_ovWrite.hEvent)
	{
		CloseHandle(m_ovWrite.hEvent);
		m_ovWrite.hEvent = NULL;
	}
	if (NULL != m_ovWait.hEvent)
	{
		CloseHandle(m_ovWait.hEvent);
		m_ovWait.hEvent = NULL;
	}
	if (NULL != m_Thread)
	{
		WaitForSingleObject(m_Thread, 5000);//等待线程结束
		CloseHandle(m_Thread);
		m_Thread = NULL;
	}
}

bool ComAsy::ComWrite(LPBYTE buf, int &len)//发送数据
{
	BOOL rtn = FALSE;
	DWORD WriteSize = 0;

	PurgeComm(m_hCom, PURGE_TXCLEAR | PURGE_TXABORT);
	m_ovWait.Offset = 0;
	rtn = WriteFile(m_hCom, buf, len, &WriteSize, &m_ovWrite);

	len = 0;
	if (FALSE == rtn && GetLastError() == ERROR_IO_PENDING)//后台读取
	{
		//等待数据写入完成
		if (FALSE == ::GetOverlappedResult(m_hCom, &m_ovWrite, &WriteSize, TRUE))
		{
			return false;
		}
	}

	len = WriteSize;
	return rtn != FALSE;

}

unsigned int __stdcall ComAsy::OnRecv(void* LPParam)//接收数据
{
	ComAsy *obj = static_cast<ComAsy*>(LPParam);

	DWORD WaitEvent = 0, Bytes = 0;
	BOOL Status = FALSE;
	BYTE ReadBuf[4096];
	DWORD Error;
	COMSTAT cs = { 0 };

	while (obj->m_IsOpen)
	{
		WaitEvent = 0;
		obj->m_ovWait.Offset = 0;
		Status = WaitCommEvent(obj->m_hCom, &WaitEvent, &obj->m_ovWait);
		//WaitCommEvent也是一个异步命令,所以需要等待
		if (FALSE == Status && GetLastError() == ERROR_IO_PENDING)//
		{
			//如果缓存中无数据线程会停在此,如果hCom关闭会立即返回False
			Status = GetOverlappedResult(obj->m_hCom, &obj->m_ovWait, &Bytes, TRUE);
		}
		ClearCommError(obj->m_hCom, &Error, &cs);
		if (TRUE == Status //等待事件成功
			&& WaitEvent&EV_RXCHAR//缓存中有数据到达
			&& cs.cbInQue > 0)//有数据
		{
			Bytes = 0;
			obj->m_ovRead.Offset = 0;
			memset(ReadBuf, 0, sizeof(ReadBuf));
			//数据已经到达缓存区,ReadFile不会当成异步命令,而是立即读取并返回True
			Status = ReadFile(obj->m_hCom, ReadBuf, sizeof(ReadBuf), &Bytes, &obj->m_ovRead);
			PurgeComm(obj->m_hCom, PURGE_RXCLEAR | PURGE_RXABORT);
			for (int i = 0; i < 4096; i++)
				aaaa[i] = ReadBuf[i];
		}

	}
	return 0;
}

1.头文件


#include "Com.h"

public:
	ComAsy  m_ca;

1.源文件:使用

	m_ca.InitCOM(L"COM3");
	char sData1[MAX_PATH] = { 0 };
	sData1[0] = 0x15;
	sData1[1] = 0x06;
	sData1[2] = 0x00;
	sData1[3] = 0x00;
	sData1[4] = 0x00;
	sData1[5] = 0x01;
	sData1[6] = 0x4B;
	sData1[7] = 0x1E;
	//sData1[5] = 0x02;
	//sData1[6] = 0x0B;
	//sData1[7] = 0x1F;
	int ii = 8;
	m_ca.ComWrite((LPBYTE)sData1, ii);
	//m_ca.UninitCOM();

1.效果

1.注意

①UninitCOM:不能在ComWrite后面立马使用,否则串口信号还米有发送过去就关闭串口了,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值