【问题标题】:Cannot read anything from the COM port (hex values)无法从 COM 端口读取任何内容(十六进制值)
【发布时间】:2020-01-12 07:30:50
【问题描述】:

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

但是,当我尝试执行 C++ 实现时,我无法从端口读取任何字节。这是我的程序,based in this answer:

#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-port serial-communication


    【解决方案1】:

    也许你需要禁用握手:

    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;
    

    【讨论】:

      【解决方案2】:

      我有错误格式的命令的十六进制值,这是他们应该如何去:

      unsigned char buffer[20] = { 0x00 };
      unsigned char init[] = { 0x50, 0x00, 0x00, 0x05, 0x55};
      

      感谢微软论坛的this answer!

      【讨论】:

        猜你喜欢
        • 2016-03-21
        • 2013-11-20
        • 2019-09-19
        • 2014-02-25
        • 2020-05-01
        • 2015-12-25
        • 2014-02-18
        • 1970-01-01
        • 2015-05-01
        相关资源
        最近更新 更多