返回

如何在 C++ 中从同一串口同时读取和写入数据?

windows

如何从同一端口同时读取和写入数据?

作为程序员,我们经常需要处理与串行端口的交互。在某些情况下,我们可能希望从同一端口同时读取和写入数据。虽然这在理论上是可能的,但在实践中需要考虑一些注意事项。

注意事项

  • 访问模式: 在打开端口时,指定允许同时读取和写入的访问模式(例如:GENERIC_READ | GENERIC_WRITE)。
  • 文件锁: 防止多个进程或线程访问同一文件,导致数据损坏或读写冲突。使用文件锁协调访问。
  • 并发访问: 使用互斥锁或信号量,同步对端口的访问,避免数据混乱或死锁。

问题

根据提供的代码,无法从同一端口同时读取和写入数据的原因可能是:

  • 端口打开方式:portInfoChecker() 函数中,使用 OPEN_EXISTING 标志打开端口。而在 dataLoggingToFile() 函数中,未指定此标志,可能会导致重新创建端口而不是打开现有端口。

解决方案

dataLoggingToFile() 函数中,添加 OPEN_EXISTING 标志到 CreateFile() 调用:

BTSerial = CreateFile(BTPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

完整代码

// ... 略 ...

void dataLoggingToFile(FILE* file, char* BTPortName)
{
    HANDLE BTSerial;
    DCB dcbSerialParams = {0};
    COMMTIMEOUTS timeouts = {0};
    DWORD bytesRead;
    char binaryStringBuffer[1024];

    // Open the serial port
    BTSerial = CreateFile(BTPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (BTSerial == INVALID_HANDLE_VALUE) 
    {
        printf("Error opening serial port %s\n", BTPortName);
        return;
    }

    // Set serial port parameters
    // ... 略 ...

    // Set timeouts
    // ... 略 ...

    while(1) // While loop to keep reading the COM port
    {
        if (ReadFile(BTSerial, buffer, sizeof(buffer), &bytesRead, NULL))
        {
            // ... 略 ...
        }
        else
        {
            // ... 略 ...
        }
    }

    CloseHandle(BTSerial);
}

结论

同时从同一端口读取和写入数据是可行的,但需要考虑上述注意事项。通过正确打开端口并处理并发访问,我们可以实现数据交互的无缝和高效进行。

常见问题解答

  1. 什么时候需要同时读取和写入同一端口?

    • 当你需要与设备进行双向通信时,例如控制设备或接收反馈。
  2. 如何处理并发访问问题?

    • 使用互斥锁或信号量,协调对端口的访问,确保一次只有一个线程或进程可以访问端口。
  3. 为什么在 dataLoggingToFile() 函数中需要 OPEN_EXISTING 标志?

    • 确保该函数打开现有端口,而不是重新创建端口,这将导致数据丢失。
  4. 如何设置串行端口参数?

    • 使用 GetCommState()SetCommState() 函数,设置串行端口的波特率、字节大小、停止位和奇偶校验。
  5. 如何处理超时?

    • 使用 SetCommTimeouts() 函数,设置端口的读写超时时间,以防止进程无限等待数据。