首页 > 解决方案 > 无法从 COM 端口读取任何内容(十六进制值)

问题描述

我正在尝试将我的 C++ 应用程序配置为使用 COM 端口与设备进行通信。我目前可以使用 HTerm 软件做到这一点:

术语

但是,当我尝试执行 C++ 实现时,我无法从端口读取任何字节。这是我的程序,基于此答案

#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <string>

#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

std::wstring s2ws(const std::string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

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

    int ch;
    char buffer[10] = {"\0"};
    HANDLE file;
    COMMTIMEOUTS timeouts;
    DWORD read, written;
    DCB port;
    HANDLE keyboard = GetStdHandle(STD_INPUT_HANDLE);
    DWORD mode;
    std::wstring port_name = s2ws("\\\\.\\COM4");
    char init[] = "5000000555";

    // open the comm port.
    file = CreateFile(port_name.c_str(),
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);

    if (INVALID_HANDLE_VALUE == file) {
        printf("opening file");
        return 1;
    }

    // get the current DCB, and adjust a few bits to our liking.
    memset(&port, 0, sizeof(port));
    port.DCBlength = sizeof(port);
    if (!GetCommState(file, &port))
        printf("getting comm state");

    if (!SetCommState(file, &port))
        printf("adjusting port settings");

    DCB dcbSerialParams = { 0 };                         // Initializing DCB structure
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

    dcbSerialParams.BaudRate = CBR_115200;      // Setting BaudRate = 115200
    dcbSerialParams.ByteSize = 8;             // Setting ByteSize = 8
    dcbSerialParams.StopBits = ONESTOPBIT;    // Setting StopBits = 1
    dcbSerialParams.Parity = NOPARITY;

    if (!GetCommState(file, &dcbSerialParams))
        printf("getting serial params");

    if (!SetCommState(file, &dcbSerialParams))
        printf("adjusting serial params");// Setting Parity = None 

    SetCommState(file, &dcbSerialParams);  //Configuring the port according to settings in DCB

    PurgeComm(file, PURGE_TXABORT | PURGE_RXABORT); // Clear up the queue

    // set short timeouts on the comm port.
    timeouts.ReadIntervalTimeout = 1;
    timeouts.ReadTotalTimeoutMultiplier = 1;
    timeouts.ReadTotalTimeoutConstant = 1;
    timeouts.WriteTotalTimeoutMultiplier = 1;
    timeouts.WriteTotalTimeoutConstant = 1;
    if (!SetCommTimeouts(file, &timeouts))
        printf("setting port time-outs.");

    // basic terminal loop:
    do {
        if (!WriteFile(file, init, sizeof(init), &written, NULL)) {
            printf("writing data to port");
        }
        else {
            printf("written %lu bytes\n", written);
        }

        Sleep(1000);

        if (written != sizeof(init))
            printf("not all data written to port");

        // check for data on port and display it on screen.
        BOOL Status = ReadFile(file, buffer, sizeof(buffer), &read, NULL);
        if (Status) {
            printf("received %lu bytes\n", read);
        }

        // check for keypress, and write any out the port.
        if (_kbhit()) {
            ch = _getch();
            WriteFile(file, &ch, 1, &written, NULL);
            printf("closing...");
        }
        // until user hits ctrl-backspace.
    } while (ch != 127);

    // close up and go home.
    CloseHandle(keyboard);
    CloseHandle(file);
    return 0;
}

这是控制台中的输出:

written 11 bytes
received 0 bytes
written 11 bytes
received 0 bytes
....

关于发生了什么的任何想法?

编辑 1

正如@rveerd 建议的那样,我尝试使用这些行禁用握手,结果相同:

dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE;
dcbSerialParams.fDtrControl = DTR_CONTROL_DISABLE;
dcbSerialParams.fOutxCtsFlow = 0;
dcbSerialParams.fOutxDsrFlow = 0;
dcbSerialParams.fNull = 0;
dcbSerialParams.fOutX = 0;
dcbSerialParams.fInX = 0;

标签: c++visual-c++serial-portserial-communication

解决方案


Maybe you need to disable handshaking:

dcbSerialParamsfBinary = TRUE;
dcbSerialParamsfOutxCtsFlow = FALSE; // CTS output handshaking.
dcbSerialParamsfOutxDsrFlow = FALSE; // DSR output handshaking.
dcbSerialParamsfDtrControl = DTR_CONTROL_DISABLE; // DTR handshaking.
dcbSerialParamsfDsrSensitivity = FALSE; // DSR input control.
dcbSerialParamsfTXContinueOnXoff = TRUE;
dcbSerialParamsfOutX = FALSE; // XON/XOFF data flow control.
dcbSerialParamsfInX = FALSE; // XON/XOFF data flow control.
dcbSerialParamsfErrorChar = FALSE;
dcbSerialParamsfNull = FALSE;
dcbSerialParamsfRtsControl = RTS_CONTROL_DISABLE; // RTS handshaking.
dcbSerialParamsfAbortOnError = FALSE;
dcbSerialParamswReserved = 0;
dcbSerialParamsXonLim = 0;
dcbSerialParamsXoffLim = 0;
dcbSerialParamsXonChar = 0;
dcbSerialParamsXoffChar = 0;
dcbSerialParamsErrorChar = 0;
dcbSerialParamsEofChar = 0;
dcbSerialParamsEvtChar = 0;

推荐阅读