Implementation of reading and writing serial ports (1)

Windows opens the serial port, reads and writes the serial port, and automatically recognizes the serial port

The serial port is read and written asynchronously, that is, non-blocking mode for reading and writing serial ports

The name of the serial port is like: "COM3", "COM4", "COM22", etc.

Among them, COM1 to COM9 can be successfully opened, but COM10 and above all fail to open, and special treatment is required

And the opening methods above COM10 are: "\\\\.\\COM10", "\\\\.\\COM11", "\\\\.\\COM22", etc. This is the serial port name above COM10 Open method



Open the serial port:

//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;
}

Initialize the serial port:

//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;
}

Serial port

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;
}

Write serial port

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;
}





















Guess you like

Origin blog.csdn.net/wzc18743083828/article/details/42008501