读写串口的实现(一)

Windows打开串口,读写串口,自动识别串口

该串口读写是采用异步方式,即非阻塞模式进行读写串口

串口名形如: "COM3", "COM4", "COM22"等

其中COM1至COM9能成功打开,但是COM10及以上打开都是失败的,需要特殊处理

及COM10以上的打开方式是: “\\\\.\\COM10”, "\\\\.\\COM11", "\\\\.\\COM22"等,这是COM10即以上的串口名打开方式



打开串口:

//Open the UART
BOOL OpenUartPort(char *UartPortName)
{
	BOOL bResult = true;
	hComm = CreateFile(
					  UartPortName, 
					  GENERIC_WRITE | GENERIC_READ,	//访问权限
					  0,							//不共享
					  NULL,							//返回的句柄不允许被子进程继承
					  OPEN_EXISTING,
					  FILE_FLAG_OVERLAPPED,							//0:同步模式,FILE_FLAG_OVERLAPPED:异步模式
					  0								//不使用临时文件句柄
					  );
	if(INVALID_HANDLE_VALUE == hComm)
	{
		PrintLogCom("Open Failed!!!\n");
		bResult = false;
	}
	else
	{
		PrintLogCom("Open Successfully!!!\n");
		if(InitUartPort(hComm, 9600, 8, NOPARITY, ONESTOPBIT))
		{
			PrintLogCom("Init Uart Port OK!!!\n");
		}
		else
		{
			//PrintLogCom("Init Uart Port Failed!!!\n");
			bResult = false;
			Close_UartPort();
		}
	}

	return bResult;
}

初始化串口:

//Init UART
BOOL InitUartPort(HANDLE hComm, DWORD BaudRate, BYTE ByteSize, BYTE Parity, BYTE StopBits)
{
	BOOL bResult = true;
	char buffer[50]="";

	//设置接收缓冲区和输出缓冲区的大小
	DWORD dwInQueue = 1024;
	DWORD dwOutQueue = 1024;
	if(!SetupComm(hComm, dwInQueue, dwOutQueue))
	{
		//PrintLogCom("Set In and Out Buffer Failed!!!\n");
		bResult = false;
	}
	else
	{
		//PrintLogCom("Set Input and Output Buffer OK!!!\n");

		//设置读写的超时时间  以毫秒计算
		COMMTIMEOUTS timeouts;
		//for read ReadTotalTimeouts = ReadTotalTimeoutMultiplier * ToReadByteNumber + ReadTotalTimeoutConstant,
		timeouts.ReadIntervalTimeout = MAXDWORD;					//接收两个字符之间的最长超时时间
		timeouts.ReadTotalTimeoutMultiplier = 0;			//与读取要读字节数相乘的系数
		timeouts.ReadTotalTimeoutConstant = 0;				//读取总超时时间常量
		//for write WriteTotalTimeouts = WriteTotalTimeoutMultiplier * ToWriteByteNumber + WriteTotalTimeoutConstant
		//timeouts.WriteTotalTimeoutMultiplier = 0;
		//timeouts.WriteTotalTimeoutConstant = 0;

		if(!SetCommTimeouts(hComm, &timeouts))
		{
			//PrintLogCom("Set Read/Write Timeouts Failed!!!\n");
			bResult = false;
		}
		else
		{
			//PrintLogCom("Set Read/Write Timeouts OK!!!\n");
			//设置DCB(Device-Control-Block)
			DCB dcb;
			if(!GetCommState(hComm, &dcb))
			{
				//PrintLogCom("Get Com DCB Failed!!!\n");
				bResult = false;
			}
			else
			{
				//PrintLogCom("Get Com DCB Successfully!!!\n");
/*				
				sprintf(buffer,"BaudRate = %ld",dcb.BaudRate);
				PrintLogCom(buffer);
				sprintf(buffer,"ByteSize = %u\n",dcb.ByteSize);
				PrintLogCom(buffer);
				sprintf(buffer,"Parity = %u\n",dcb.Parity);
				PrintLogCom(buffer);
				sprintf(buffer,"StopBits = %u\n",dcb.StopBits);
				PrintLogCom(buffer);
				sprintf(buffer,"XonChar = %d\n", dcb.XonChar);
				PrintLogCom(buffer);
*/
				memset(&dcb, 0, sizeof(dcb));
				dcb.BaudRate = BaudRate;
				dcb.ByteSize = ByteSize;
				dcb.Parity = Parity;
				dcb.StopBits = StopBits;
				dcb.XonChar = 1;
	
				if(!SetCommState(hComm, &dcb))
				{
					//PrintLogCom("Set Com Failed!!!\n");
					bResult = false;
				}
				else
				{
					//PrintLogCom("Set Com Successfully!!!\n");

					//清空接收缓存和输出缓存的buffer
					if(!PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR))
					{
						//PrintLogCom("Clean up in buffer and out buffer Failed!!!\n");
						bResult = false;
					}
					else
					{
						//PrintLogCom("Clean up in buffer and out buffer OK!!!\n");
					}
				}
			}
		}
	}

	return bResult;
}

读串口

BOOL RcvDataFromUartPort(HANDLE hComm, void *RcvBuf, DWORD ToRcvDataLen, DWORD *RcvedDataLen, LPOVERLAPPED lpOverlapped)
{
	BOOL bResult = true;
	DWORD dwTempRcvedDataLen = 0;
	DWORD dwError;

	if (ClearCommError(hComm,&dwError,NULL))
	{
		PurgeComm(hComm,PURGE_TXABORT | PURGE_TXCLEAR);
	}

	if(hComm != INVALID_HANDLE_VALUE)
	{
		if(!ReadFile(hComm, RcvBuf, ToRcvDataLen, &dwTempRcvedDataLen, lpOverlapped))
		{
			if (GetLastError() == ERROR_IO_PENDING)
			{
				while (!GetOverlappedResult(hComm,lpOverlapped,&dwTempRcvedDataLen,FALSE))
				{
					if (GetLastError() == ERROR_IO_INCOMPLETE)
					{
						continue;
					}
					else
					{
						ClearCommError(hComm,&dwError,NULL);
						bResult = false;
						break;
					}
				}
			}
		}
	}
	else
	{
		bResult = false;
	}
	*RcvedDataLen = dwTempRcvedDataLen;
	return bResult;
}

写串口

BOOL SendDataToUartPort(HANDLE hComm, void *SndBuf, DWORD SendDataLen, DWORD *SentDataLen, LPOVERLAPPED lpOverlapped)
{
	BOOL bResult = true;
	DWORD dwTempSndDataLen;
	DWORD dwError;

	if (ClearCommError(hComm,&dwError,NULL))
	{
		PurgeComm(hComm,PURGE_TXABORT | PURGE_TXCLEAR);
	}

	if(hComm != INVALID_HANDLE_VALUE)
	{
		if(!WriteFile(hComm, SndBuf, SendDataLen, &dwTempSndDataLen, lpOverlapped))
		{
			if (GetLastError() == ERROR_IO_PENDING)
			{
				while (!GetOverlappedResult(hComm,lpOverlapped,&dwTempSndDataLen,FALSE))
				{
					if (GetLastError() == ERROR_IO_INCOMPLETE)
					{
						continue;
					}
					else
					{
						ClearCommError(hComm,&dwError,NULL);
						bResult = false;
						break;
					}
				}
			}
		}
	}
	else
	{
		bResult = false;
	}
	*SentDataLen = dwTempSndDataLen;

	return bResult;
}





















  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值