从COM端口

时间:2015-06-29 17:54:01

标签: c++ windows winapi serial-port

我正在尝试读取在一个COM端口上发送并在另一个COM端口上接收的消息。这两个端口通过两个USB转串口转换器连接。当我尝试读取传输的消息时,我得到了这个:

Tx波特率:9600 Rx波特率:9600 试图阅读...... 你好,是╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠á☼ 做...

按任意键继续。 。

该消息应为“你好,那里有人吗??”

我们是我写的代码:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <Windows.h>

typedef struct COMDevice {
    HANDLE deviceHandle;
    DWORD actualBytesReadOrWritten;
    int deviceStatus;
    std::string message;
    DCB controlSettings;
} COMDevice;

int main(int argc, char *argv[]) {

// create new device
COMDevice *comWriter = new COMDevice;
COMDevice *comReader = new COMDevice;
// setup
comWriter->deviceHandle = NULL;
comWriter->actualBytesReadOrWritten = 0;
comWriter->deviceStatus = 0;
comWriter->message = "Hello, is there anybody out there!?";

comReader->deviceHandle = NULL;
comReader->actualBytesReadOrWritten = 0;
comReader->deviceStatus = 0;
comReader->message = "";

// open COM1 for writing
comWriter->deviceHandle = CreateFile(TEXT("COM5"), GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
if(comWriter->deviceHandle == INVALID_HANDLE_VALUE) {
        std::cout << "Error occurred opening port for writing...\n";
        return (int)GetLastError();
}

    // open COM4 for reading
    comReader->deviceHandle = CreateFile(TEXT("COM4"), GENERIC_READ, 0, 0, OPEN_ALWAYS, 0, 0);
    if(comReader->deviceHandle == INVALID_HANDLE_VALUE) {
        std::cout << "Error occurred opening port for reading...\n";
        return (int)GetLastError();
    }

    // check baud rates
    if(GetCommState(comWriter->deviceHandle, &comWriter->controlSettings) == 0 || 
    GetCommState(comReader->deviceHandle, &comReader->controlSettings) == 0) {
        std::cout << "Error occurred getting the comm state...\n";
        return (int)GetLastError();
    }
    else {
        std::cout << "Tx Baud rate: " << comWriter->controlSettings.BaudRate << std::endl;
        std::cout << "Rx Baud rate: " << comReader->controlSettings.BaudRate << std::endl;
    }

    // write message to serial port
    comWriter->deviceStatus = WriteFile(comWriter->deviceHandle, comWriter->message.c_str(), 
    comWriter->message.length(), &comWriter->actualBytesReadOrWritten, NULL);
    if(comWriter->deviceStatus == FALSE) {
        std::cout << "Error occurred writing to port..\n";
        return (int)GetLastError();
    }

    // wait a few
    int i = 0, count = 4000;
    while(i < count) { i++; }

    // read
    std::cout << "Attempting to read...\n";
    char buffer[1024];
    comReader->deviceStatus = ReadFile(comReader->deviceHandle, buffer, 1023, 
    &comReader->actualBytesReadOrWritten, NULL);
    if(comReader->deviceStatus == FALSE) {

        return (int)GetLastError();
    }
    std::cout << buffer << std::endl;

    // close handles
    (void)FlushFileBuffers(comReader->deviceHandle);
    (void)CloseHandle(comWriter->deviceHandle);
    (void)CloseHandle(comReader->deviceHandle);

    // clean up...
    delete comWriter;
    delete comReader;

    std::cout << "Done...\n";

return 0;
}

我还使用DCB结构检查两端的波特率......它们匹配。还有其他我可能会遗失的东西吗?

1 个答案:

答案 0 :(得分:3)

使用

从串口读取时
ReadFile(comReader->deviceHandle, buffer, 1023, 
    &comReader->actualBytesReadOrWritten, NULL);

读取的实际字节数存储在comReader->actualBytesReadOrWritten(第4个参数)中。但是你没有用它来打印。最终的结果是你读了几个字节,然后你尝试打印它们,但由于它们不是NUL终止的,你打印文本和大量垃圾,直到它碰巧找到一个NUL字符(或崩溃)

简单的解决方案是在ReadFile

之后放置一个NUL字符
buffer[comReader->actualBytesReadOrWritten] = '\0';

但是,实际上存在的问题是您还没有收到所有字节。有几种方法可以确保所有数据都已被读取,重试,等待一段时间......再次重试......

提示

字符'╠',如果您在旧版OEM codepage中查找它,则为字节0xCC,(它将是'Ì'与ANSI西部代码页),即VC ++用于填充调试版本中未初始化的堆栈空间的字节。因此,很多这些字符强烈建议使用未初始化的本地缓冲区。