CreateFile系类异步、并行(同一个串口发送接收)

windows 同时被 2 个专栏收录
14 篇文章 0 订阅
13 篇文章 4 订阅

  在Windows系统下,串口数据收发CreateFile系类方法对于我来说是最好用的方法,采用异步机制保证了串口读或写入不会使代码停在串口函数内(停在串口函数内原因可能是串口线的原因,或者串口没打开(这个是猜测)),并且可以达到同一个串口既发送并接收(测试方法:串联串口线)。

下面说下CreateFile函数串口创建打开、初始化串口以及串口关闭:
  函数定义如下:

WINBASEAPI
__out
HANDLE
WINAPI
CreateFile(
    __in     LPCWSTR lpFileName,
    __in     DWORD dwDesiredAccess,
    __in     DWORD dwShareMode,
    __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    __in     DWORD dwCreationDisposition,
    __in     DWORD dwFlagsAndAttributes,
    __in_opt HANDLE hTemplateFile
    );

  函数使用如下:

 串口异步打开:
    
	m_hWriteFile = CreateFile("COM1",GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	if ((HANDLE)0 == m_hWriteFile || (HANDLE)-1 == m_hWriteFile)
	{
			MessageBox("没有打开串口,或者串口被占用!");
	}

 串口初始化配置:
  SetupComm(m_hWriteFile,4096,1);//设置输入输出缓冲区
			DCB dcb;
			GetCommState(m_hWriteFile,&dcb);
			dcb.BaudRate = 115200;//比特率
			dcb.ByteSize = 8;
			dcb.Parity = NOPARITY;
			dcb.StopBits = /*TWOSTOPBITS*/ONESTOPBIT;//停止位
			SetCommState(m_hWriteFile,&dcb);//设置串口状态
			PurgeComm(m_hWriteFile,PURGE_TXCLEAR | PURGE_RXCLEAR);

  串口关闭:
  if ((HANDLE)0 != m_hWriteFile && (HANDLE)-1 != m_hWriteFile)
		{
			CloseHandle(m_hWriteFile);
			m_hWriteFile = NULL;
		}

下面说下WriteFile异步写入串口数据方法:
  函数定义如下:

WINBASEAPI
BOOL
WINAPI
WriteFile(
    __in        HANDLE hFile,
    __in_bcount_opt(nNumberOfBytesToWrite) LPCVOID lpBuffer,
    __in        DWORD nNumberOfBytesToWrite,
    __out_opt   LPDWORD lpNumberOfBytesWritten,
    __inout_opt LPOVERLAPPED lpOverlapped
    );

  函数使用如下:

OVERLAPPED ov;//异步数据储存的结构体
OMSTAT comstat;//串口结构体 ,用来清除串口错误 建议每次写数据前都清除一下
memset(&comstat,0,sizeof(comstat));
ClearCommError(collet->m_hWriteFile,&dwError,&comstat);

DWORD dwBytesRead = 0;
memset(&ov,0,sizeof(OVERLAPPED));
ov.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);//创建一个事件
BOOL bGetRead = WriteFile(collet->m_hWriteFile,SendFileStr,1,&dwBytesRead,&ov);
DWORD wait = WaitForSingleObject(ov.hEvent,1000);//设置一个事件超时时间 
if (0 != ov.InternalHigh)//数据实际接收字节数
{
	nGetFilelength -= ov.InternalHigh;
}
else if (0 != dwBytesRead)
{
	nGetFilelength -= dwBytesRead;
}

下面说下ReadFile异步读取串口方法:
  函数定义如下:

WINBASEAPI
BOOL
WINAPI
ReadFile(
    __in        HANDLE hFile,
    __out_bcount_part_opt(nNumberOfBytesToRead, *lpNumberOfBytesRead) __out_data_source(FILE) LPVOID lpBuffer,
    __in        DWORD nNumberOfBytesToRead,
    __out_opt   LPDWORD lpNumberOfBytesRead,
    __inout_opt LPOVERLAPPED lpOverlapped
    );

  函数使用如下:

DWORD dwError = 0;
COMSTAT comstat;//串口结构体 用来清除串口错误 ,建议每次读数据时都要先清除一下
memset(&comstat,0,sizeof(comstat));
ClearCommError(collet->m_hWriteFile,&dwError,&comstat);
if (0 == comstat.cbInQue)//判读是否有数据需要接收
{
	continue;
}
DWORD dwBytesRead = 0;
memset(&ov,0,sizeof(OVERLAPPED));
ov.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);//创建事件
BOOL bGetRead = ReadFile(collet->m_hWriteFile,WriteFileStr,1,&dwBytesRead,&ov);
DWORD wait = WaitForSingleObject(ov.hEvent,1000);//设置事件超时时间
if (0 != ov.InternalHigh)
{
	nWriteTextLen += ov.InternalHigh;
}
else if (0 != dwBytesRead)
{
	nWriteTextLen += dwBytesRead;
}


使用说明:
  1.ReadFile与WriteFile方法使用同一个串口句柄(同一个串口)可以达到同一个串口边发送边接收。
  2.建议每次读或写串口的时候,先清空一下串口错误。
  3.建议专门做个函数用来管理串口的打开与关闭,方便’并行’的使用。

  • 1
    点赞
  • 0
    评论
  • 4
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

参与评论
请先登录 后发表评论~
©️2021 CSDN 皮肤主题: 博客之星2020 设计师:CY__ 返回首页

打赏作者

坤昱

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值