在窗口中通过串行写入二进制数据
Writing binary data over serial in windows
>我需要通过串行端口发送二进制数据,在此过程中不会将任何字节重新解释为控制字符。我目前正在按如下方式设置我的串行端口:
#include <windows.h>
// open serial port
HANDLE hSerial;
hSerial = CreateFile ("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
// get serial parameters
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength = sizeof (dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
cout << "error getting staten";
exit(0);
}
// set serial params
dcbSerialParams.BaudRate = CBR_115200;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState (hSerial, &dcbSerialParams)) {
cout << "error setting parametersn";
exit(0);
}
// set time outs
COMMTIMEOUTS timeouts = {0};
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 10;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 10;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts (hSerial, &timeouts)) {
cout << "problem setting timeout valuesn";
exit(0);
} else cout << "timeouts setn";
当我发出 ReadFile 命令时,我可以毫无问题地获取和显示从 0 到 255 的字节。 但我对 WriteFile 没有这样的运气。有没有办法显式设置二进制写入模式?
编辑
好的,这里有一些更多信息。我有一台Windows机器和一台linux单板计算机通过串行连接,上面在Windows端的代码后跟:
unsigned char temp = 0;
bool keepReading = true;
while (keepReading) {
DWORD dwBytesRead = 0;
ReadFile (hSerial, &temp, 1, &dwBytesRead, NULL);
if (1 == dwBytesRead) cout << (unsigned int) temp << " ";
if (255 == temp) keepReading = false;
}
cout << endl;
bool keepWriting = true;
char send = 0;
while (keepWriting) {
DWORD dwBytesWritten = 0;
WriteFile (hSerial, &send, 1, &dwBytesWritten, NULL);
send++;
if (256 == send) keepWriting = false;
}
我在 linux 端的代码如下所示:
int fd = open("/dev/ttymxc0", O_RDWR | O_NOCTTY);
struct termios options;
bzero (options, sizeof(options));
options.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
options.c_iflat = IGNPAR;
options.c_oflag = 0;
options.c_lflag = ICANON;
options.c_cc[VMIN] = 1;
options.c_CC[VTIME] = 0;
tcflush (fd, TCIFLUSH);
tcsetattr (fd, ICSANOW, &options);
bool keepWriting = true;
char send = 0;
while (keepWriting) {
write (fd, &send, 1);
send++;
if (256 == send) keepWriting = false;
}
bool keepReading = true;
while (keepReading) {
char temp = 0;
int n = read (fd, &temp, 1);
if (-1 == n) {
perror ("Read error");
keepReading = false;
} else if (1 == n) {
cout << temp << " ";
}
if (256 == temp) keepReading = false;
}
cout << endl;
close(fd);
我在两台机器上启动代码,第一组 while 循环运行良好。窗口侧的终端显示 0 到 255。然后它就坐在那里。如果我输出第二组 while 循环在 linux 端读取的字节数,它会持续给我 0 个字节。这通常表示端口已关闭,但我只是通过它发送了一堆信息,所以怎么可能呢?
正如Jonathan Potter所提到的,很可能你没有关闭XON/XOFF流控制。 在调用 SetCommState
之前添加以下行:
dcbSerialParams.fOutX = 0;
dcbSerialParams.fInX = 0;
您可能需要设置的其他一些字段:
dcbSerialParams.fNull = 0;
dcbSerialParams.fDtrControl = DTR_CONTROL_DISABLE;
dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE;
我认为
可能发生的情况是 Linux 检测到中断并重置端口,或者设置规范模式的事实正在搞砸它。 除了已有的设置之外,还可以尝试以下设置:
options.c_iflag |= IGNBRK;
options.c_iflag &= ~BRKINT;
options.c_iflag &= ~ICRNL;
options.c_oflag = 0;
options.c_lflag = 0;
好吧,我想通了,而是同事做的。在 linux 方面,在文件/etc/inittab 中,我不得不注释掉这一行:
T0:23:respawn:/sbin/getty -L ttymxc0 115200 vt100
这是以一种使其无法用于接收字节的方式抓取串行端口。我现在看到了预期的输出。
相关文章:
- 如何从dicom文件中读取二进制数据
- 如何在Qt中从数据库中检索二进制数据?
- readsome() 适合在 Windows 上读取二进制数据吗?
- 如何使用 redis-plus-plus 存储二进制数据,就像我想存储结构一样?@for_stack?
- 将包含二进制数据的 QByteArray 传递到按值运行
- 如何在 c++ 中生成十六进制二进制数据的 sha256 哈希?
- 在处理网络、二进制数据和序列化时应使用流或容器
- 我能确定从文件中读取的 32 字节二进制数据等于 256 位吗?
- C++:如何通过 curl 调用使用 HTTP post 请求发送二进制数据(protobuf 数据)
- 使用二进制数据更新 PostgreSQL 表
- 使用二进制数据和无符号字符
- sd_journal_send发送二进制数据.如何使用日志检索数据?
- 从带有 std::ifstream::read() 的文件中读取 int 遍历 char * 二进制数据
- 将文本和二进制数据连接到一个文件中
- 二进制模式 + 格式化文本操作或文本模式 + 二进制数据操作 - 有意义吗?
- 将整数的二进制数据转换为浮点数
- 使用 CMake 在可执行文件中嵌入二进制数据
- 二进制数据作为命令行参数
- 如何访问文件的二进制数据?
- 返回二进制数据的通用方式,而无需原始指针