我需要通过串口发送二进制数据,一路上没有任何字节被重新解释为控制字符。我目前正在设置我的串口如下:
#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 state\n";
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 parameters\n";
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 values\n";
exit(0);
} else cout << "timeouts set\n";
当我发出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循环运行正常。 Windows侧的终端显示0到255.然后它就在那里。如果我输出linux侧读取的第二组while循环的字节数,它会不断给出0字节。这通常表示一个关闭的端口,但我只是通过它发送了一堆信息,那怎么可能呢?
答案 0 :(得分:2)
我认为可能发生的事情是Linux正在检测中断,重置端口,或者设置规范模式的事实正在弄乱它。除了您已经拥有的设置之外,请尝试以下设置:
options.c_iflag |= IGNBRK;
options.c_iflag &= ~BRKINT;
options.c_iflag &= ~ICRNL;
options.c_oflag = 0;
options.c_lflag = 0;
答案 1 :(得分:2)
正如Jonathan Potter所提到的,很可能你没有关闭XON / XOFF流量控制。在调用SetCommState
之前添加这些行:
dcbSerialParams.fOutX = 0;
dcbSerialParams.fInX = 0;
您可能需要设置的其他一些字段:
dcbSerialParams.fNull = 0;
dcbSerialParams.fDtrControl = DTR_CONTROL_DISABLE;
dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE;
答案 2 :(得分:0)
好吧,所以我想出来了,而不是一个同事。在linux方面,在文件/ etc / inittab中我必须注释掉这一行:
T0:23:respawn:/sbin/getty -L ttymxc0 115200 vt100
这使得串口无法接收字节。我现在看到预期的输出。