讀寫串列埠的實現(一)
阿新 • • 發佈:2019-01-11
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;
}