无法从 COM 端口读取任何内容(十六进制值)
Cannot read anything from the COM port (hex values)
我正在尝试配置我的 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] = {"[=10=]"};
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;
也许您需要禁用握手:
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;
我的命令的十六进制值格式错误,它们应该是这样的:
unsigned char buffer[20] = { 0x00 };
unsigned char init[] = { 0x50, 0x00, 0x00, 0x05, 0x55};
感谢 MS 论坛中的 this answer!
我正在尝试配置我的 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] = {"[=10=]"};
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;
也许您需要禁用握手:
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;
我的命令的十六进制值格式错误,它们应该是这样的:
unsigned char buffer[20] = { 0x00 };
unsigned char init[] = { 0x50, 0x00, 0x00, 0x05, 0x55};
感谢 MS 论坛中的 this answer!