c++ - 串行通信 C++ ReadFile()

标签 c++ windows serial-port

我创建了 2 个函数来通过串行端口进行读写,我使用 visual studio 2012、windows 7、64 位操作系统和 RS-232 串口线使用 c++ 进行编码。我连接的开发板应该在按下按钮时发送 5 个字符,TRG 1,代码有效,但输出值并不总是正确的。

char serialRead()
{
    char input[5];
    DCB dcBus;
    HANDLE hSerial;
    DWORD  bytesRead, eventMask;
    COMMTIMEOUTS timeouts;
    hSerial = CreateFile (L"\\\\.\\COM13", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hSerial == INVALID_HANDLE_VALUE)
    {
        cout << "error opening handle\n";
    }
    else
    {
        cout << "port opened\n";
    }
    dcBus.DCBlength = sizeof(dcBus);
    if ((GetCommState(hSerial, &dcBus) == 0))
    {
        cout << "error getting comm state\n";
    }
    dcBus.BaudRate = CBR_9600;
    dcBus.ByteSize = DATABITS_8;
    dcBus.Parity = NOPARITY;
    dcBus.StopBits = ONESTOPBIT;
    if ((GetCommState(hSerial, &dcBus) == 0))
    {
        cout << "error setting comm state\n";
    }
    if ((GetCommTimeouts(hSerial, &timeouts) == 0))
    {
        cout << "error getting timeouts\n";
    }
    timeouts.ReadIntervalTimeout = 10;
    timeouts.ReadTotalTimeoutMultiplier = 1;
    timeouts.ReadTotalTimeoutConstant = 500;
    timeouts.WriteTotalTimeoutMultiplier = 1;
    timeouts.WriteTotalTimeoutConstant = 500;
    if (SetCommTimeouts(hSerial, &timeouts) == 0)
    {
        cout << "error setting timeouts\n";
    }
    if (SetCommMask(hSerial, EV_RXCHAR) == 0)
    {
        cout << "error setting comm mask\n";
    }
    if (WaitCommEvent(hSerial, &eventMask, NULL))
    {
        if (ReadFile(hSerial, &input, 5, &bytesRead, NULL) !=0)
        {
            for (int i = 0; i < sizeof(input); i++)
            {
                cout << input[i];
            }
            cout << endl;
        }
        else 
        {
            cout << "error reading file\n";
        }
    }
    else
    {
        cout << "error waiting for comm event\n";
    }
    switch (input[4])
    {
    case '1' :
        CloseHandle(hSerial);
        return '1';
        break;
    case '2' :
        CloseHandle(hSerial);
        return '2';
        break;
    case '3' :
        CloseHandle(hSerial);
        return '3';
        break;
    case '4' :
        CloseHandle(hSerial);
        return '4';
        break;
    case '5':
        CloseHandle(hSerial);
        return '5';
        break;
    default :
        CloseHandle(hSerial);
        return '9';
        break;
    }
}

从正确配置端口并且正在传输数据的意义上来说,代码运行成功。输出各不相同,大多数时候输出会打印整个“TRG 1”,但随机(看起来),输出将是“TRG|}|}”或“T|}|}|}|}”,即它将成为字符串的一部分,并且每个缺失的字符都将被替换为“|}”而不是正确的字符。这是一个问题,因为我希望能够为触发器发送不同的值并运行该变量的开关。

我是串行通信的新手,不是专业的程序员,所以我想知道发生了什么?

最佳答案

串行通信不是基于数据包的。这些信息不会打包发送给您,在这种情况下,您必须一次性阅读整条消息;相反,它是一个流,因此您可以阅读半条消息、整条消息、多条消息等。

正如 zdan 在评论中所说,您需要检查从 ReadFile 读取的字节数,并使用它来组成 5 个字符的包,这是您的消息。 具体来说,只有前几个字符到返回的读取字节数是有效的;其余的都是垃圾。

关于c++ - 串行通信 C++ ReadFile(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29780665/

相关文章:

java - 如何在 Windows 和 Mac 上为 Java 应用程序设置正确的字体?

windows - 在 powershell 脚本中以不同用户身份在本地运行代码块

c++ - 串口流量控制

c - C语言串口通信

c++ - 如何将 UTF-8 字符串的一部分解析为 C++ 字符串?

c++ - 为什么使用运算符 = 进行引用可以,但使用构造函数则不行?

c++ - 使用 C++ 如何从 void 函数传递值?

c++ - 如何在 Visual Studio 中测试已编译的 DLL(或生成多个可执行文件)?

c++ - 如何在 InitializeObjectAttributes() 中使用 SECURITY_DESCRIPTOR

c# - 在 C# 中以编程方式更改串行端口配置