1、打开串口设备,使用CreateFile来打开串口设备进行操作,视例代码如下 HANDLE m_hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, // read/write types 0, // comm devices must be opened with exclusive access NULL, // no security attributes OPEN_EXISTING, // comm devices must use OPEN_EXISTING FILE_FLAG_OVERLAPPED, // Async I/O 0); // template must be 0 for comm devices
2、初始化打口串口的参数和配置,代码如下,如果不明白函数的使用方法,可以查看msdn// set the timeout values m_CommTimeouts.ReadIntervalTimeout = 1000; m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000; m_CommTimeouts.ReadTotalTimeoutConstant = 1000; m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000; m_CommTimeouts.WriteTotalTimeoutConstant = 1000; // configure if (FALSE == SetCommTimeouts(m_hComm, &m_CommTimeouts)) { ProcessErrorMessage(_T("SetCommTimeouts()")); break; } if (FALSE == SetCommMask(m_hComm, dwCommEvents)) { ProcessErrorMessage(_T("SetCommMask()")); break; } if (FALSE == GetCommState(m_hComm, &m_dcb)) { ProcessErrorMessage(_T("GetCommState()")); break; } m_dcb.fRtsControl = RTS_CONTROL_ENABLE; // set RTS bit high! if (FALSE == BuildCommDCB(szBaud, &m_dcb)) { ProcessErrorMessage(_T("BuildCommDCB()")); break; } if (FALSE == SetCommState(m_hComm, &m_dcb)) { ProcessErrorMessage(_T("SetCommState()")); break; } // flush the port if(FALSE == PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT)) { ProcessErrorMessage(_T("PurgeComm()")); //break; }
3、因为串口通迅要独立于界面操作,需要单独创建线程,监测串口的读写等事件,进行数据的收发操作,要多查阅文档熟悉这些事件操作bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov); if (!bResult) { switch (dwError = GetLastError()) { case ERROR_IO_PENDING: { break; } case 87: { break; } default: { port->ProcessErrorMessage(_T("WaitCommEvent()")); break; } } } else { bResult = ClearCommError(port->m_hComm, &dwError, &comstat); if (comstat.cbInQue == 0) continue; } Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE); switch (Event) { case 0: { AfxEndThread(100); break; } case 1: // read event { ReceiveChar(port, &comstat); break; } case 2: // write event { WriteChar(port); break; } }
4、实现往串口发送的函数PurgeComm 和WriteFilePurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);清除发送缓冲区WriteFile往串口发送数据
5、因为串口发送比较缓慢,数据发送的缓存区需要加锁保护,不然数据会错误,导致文件不能正常打开,需要熟悉锁和事件的使用函数,EnterCriticalSectionLeaveCriticalSectionSetEvent等函数的使用方法注:要等待发送缓冲区的数据发送完全,才能继续发送
6、因为串口通迅数据并不可靠,最好还要加上收发确认功能,或者由接收方主动请求比较好,涉及到串口读操作的函数ReadFile
7、由于文章篇幅限制,只提供解决的思路流程和用到的函数,自行查阅函数的使用方法,函数文档非常详细