c++ - 无法从 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;
解决方案
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;
推荐阅读
- c++ - C / C++ 服务器什么都不返回,客户端如何知道套接字或以太网连接断开/断开?
- javascript - jQuery 匹配一个包含所有类的元素
- python - TAPI ITAddressDeviceSpecificEven 如何从一个事件中获取所有数据?
- json - 如何在flutter中解析JSON数据并在vs code终端上打印?
- c - C 使用多个 go 静态库
- python - 为什么 Scrapy 在爬取主 url 之前会爬取其他一些 url?
- java-8 - 我如何从 java 中的 ISO3166-1 alpha-2 国家代码中获取国家名称
- java - Decentraland 中的 Java Selenium 鼠标移动
- svg - 如何将three.js中的3D模型的面部形状转换为2D SVG?
- spring-data-jpa - 从运行在不同服务器上的两个 Spring Boot 应用程序或具有字段子集的同一服务器映射访问相同的数据库(读/写)