逐句解释m_ovRead.hEvent = CreateEvent(NULL, false, false, NULL); m_ovWrite.hEvent = CreateEvent(NULL, false, false, NULL); m_ovWait.hEvent = CreateEvent(NULL, false, false, NULL); SetCommMask(m_hCom, EV_ERR|EV_RXCHAR|EV_TXEMPTY);
时间: 2024-04-06 17:34:08 浏览: 16
1. `m_ovRead.hEvent = CreateEvent(NULL, false, false, NULL);`
这行代码的作用是创建一个事件对象,并将其句柄赋值给`m_ovRead.hEvent`变量。`CreateEvent`函数的四个参数分别是:安全属性,是否手动重置,初始状态,对象名称。这里的参数设置为`NULL, false, false, NULL`,表示不指定安全属性,自动重置,初始状态为非信号状态,不指定对象名称。
2. `m_ovWrite.hEvent = CreateEvent(NULL, false, false, NULL);`
与第一行代码类似,这行代码的作用是创建一个事件对象,并将其句柄赋值给`m_ovWrite.hEvent`变量。
3. `m_ovWait.hEvent = CreateEvent(NULL, false, false, NULL);`
同上,这行代码的作用是创建一个事件对象,并将其句柄赋值给`m_ovWait.hEvent`变量。
4. `SetCommMask(m_hCom, EV_ERR|EV_RXCHAR|EV_TXEMPTY);`
这行代码的作用是设置串口通信的事件掩码,即指定哪些事件将触发串口通信的等待。`SetCommMask`函数的两个参数分别是:串口句柄,事件掩码。这里的事件掩码包括三个事件:错误事件(`EV_ERR`)、接收字符事件(`EV_RXCHAR`)、发送缓冲区为空事件(`EV_TXEMPTY`)。当这些事件中的任意一个发生时,将触发串口通信的等待。
相关问题
vc++6.0中用mfc实现串口通信
以下是一个简单的 VC++6.0 MFC 应用程序,演示如何使用 MFC 实现串口通信:
1. 创建一个 MFC 对话框应用程序。
2. 在 CMyDialog 类的头文件中添加以下成员变量:
```c++
HANDLE m_hComm;
OVERLAPPED m_osRead;
OVERLAPPED m_osWrite;
```
3. 在 OnInitDialog 函数中初始化串口:
```c++
CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// 初始化串口
m_hComm = CreateFile(_T("COM1"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (m_hComm == INVALID_HANDLE_VALUE)
{
MessageBox(_T("无法打开串口"), _T("错误"), MB_OK);
return TRUE;
}
SetupComm(m_hComm, 1024, 1024);
DCB dcb;
GetCommState(m_hComm, &dcb);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
SetCommState(m_hComm, &dcb);
PurgeComm(m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR);
// 初始化读写事件
m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
return TRUE;
}
```
4. 在 OnOK 函数中关闭串口:
```c++
CMyDialog::OnOK()
{
CloseHandle(m_osRead.hEvent);
CloseHandle(m_osWrite.hEvent);
CloseHandle(m_hComm);
CDialog::OnOK();
}
```
5. 实现一个函数来读取串口数据:
```c++
void CMyDialog::ReadFromPort()
{
char buf[1024];
DWORD dwRead;
if (!ReadFile(m_hComm, buf, 1024, &dwRead, &m_osRead))
{
if (GetLastError() != ERROR_IO_PENDING)
{
// 读取失败
return;
}
}
WaitForSingleObject(m_osRead.hEvent, INFINITE);
if (!GetOverlappedResult(m_hComm, &m_osRead, &dwRead, TRUE))
{
// 获取结果失败
return;
}
// 处理读取到的数据
buf[dwRead] = '\0';
AfxMessageBox(buf);
}
```
6. 实现一个函数来写入串口数据:
```c++
void CMyDialog::WriteToPort(LPCTSTR lpBuf)
{
DWORD dwWritten;
if (!WriteFile(m_hComm, lpBuf, _tcslen(lpBuf), &dwWritten, &m_osWrite))
{
if (GetLastError() != ERROR_IO_PENDING)
{
// 写入失败
return;
}
}
WaitForSingleObject(m_osWrite.hEvent, INFINITE);
if (!GetOverlappedResult(m_hComm, &m_osWrite, &dwWritten, TRUE))
{
// 获取结果失败
return;
}
// 写入成功
}
```
7. 在需要读取或写入串口数据的地方调用上述函数即可。例如,在按钮点击事件中读取串口数据:
```c++
void CMyDialog::OnButtonRead()
{
ReadFromPort();
}
```
注意,以上代码只是一个简单的示例,实际应用中还需要进行错误处理和优化。
其中 发生ERROR_IO_PENDING错误 如何不阻塞 继续接收
当使用异步I/O操作时,可能会遇到ERROR_IO_PENDING错误。这个错误表示操作已经启动,但是还没有完成。如果你想在不阻塞的情况下继续接收,你需要使用异步回调函数来处理这个错误。
在异步回调函数中,你需要检查操作的结果。如果操作成功完成,你可以处理接收到的数据。如果操作没有完成,你可以继续等待,或者尝试发起新的操作。
以下是一个示例代码,展示了如何处理ERROR_IO_PENDING错误并继续接收:
```
DWORD bytesRead = 0;
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!ReadFile(hFile, buffer, bufferSize, &bytesRead, &overlapped)) {
DWORD lastError = GetLastError();
if (lastError != ERROR_IO_PENDING) {
// 处理错误
return;
}
}
// 等待操作完成
DWORD result = WaitForSingleObject(overlapped.hEvent, INFINITE);
if (result == WAIT_OBJECT_0) {
// 操作完成
GetOverlappedResult(hFile, &overlapped, &bytesRead, FALSE);
// 处理接收到的数据
} else {
// 等待超时或错误
return;
}
```
在这个示例代码中,我们使用ReadFile函数来读取数据,如果返回ERROR_IO_PENDING错误,就表示操作已经启动。我们创建了一个OVERLAPPED结构体,并使用CreateEvent函数来创建一个事件对象。然后,我们等待操作完成,如果操作完成,我们可以使用GetOverlappedResult函数来获取结果,并处理接收到的数据。如果等待超时或错误,我们就退出函数。