我有一个串行端口。另一个程序每0.2秒写入一次串行端口。每次写入串行端口的数据总长为83个字节。可以使用minicom正确读取串行端口。
我有一个可以读取串行端口的程序。每次,写入串行端口的字节流为:
65 66 67 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
大多数时候可以正确接收数据。但是,有时数据混乱了。一旦数据混乱,几乎所有传入的消息都会混乱。
有时候,我从代码中得到的输出为:
65 0 66 67 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 65 65 66 67
这很奇怪。显然,由于前65个后面有一个0。另外,后三个字节是65 66 67,看起来像是在请求新消息。
用于打开和配置串行端口的代码为:
int serial_fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY|O_NONBLOCK);
if (serial_fd < 0) {
return -1;
}
struct termios options;
tcgetattr(serial_fd, &options);
options.c_cflag |= (CLOCAL | CREAD);
//8N1 mode
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~CSTOPB;
options.c_cflag &=~PARENB;
options.c_cflag &= ~CRTSCTS;
options.c_lflag &= ~(ICANON|ECHO|ECHONL|ISIG|IEXTEN);
options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
options.c_oflag &= ~OPOST;
cfsetospeed(&options, B115200);
cfsetispeed(&options, B115200);
tcsetattr(serial_fd, TCSANOW, &options);
tcflush(serial_fd, TCIFLUSH);
从串行端口读取并打印出接收到的消息的代码为:
uint8_t *buff,buff_data[100];
buff = buff_data;
int len,fs_sel;
fd_set fs_read;
int expectedLength=83;
int len_acc = 0;
while(1){
FD_ZERO(&fs_read);
FD_SET(serial_fd, &fs_read);
fs_sel = select(serial_fd+1,&fs_read,NULL,NULL,NULL);
if(fs_sel)
{
len = read(serial_fd, buff, expectedLength-len_acc);
if (len<=0) continue;
len_acc += len;
if (len_acc < expectedLength) {
buff += len;
continue;
}
len_acc = 0;
buff = buff_data;
for (int i=0; i<expectedLength; i++){
std::cout <<(int)buff[i]<<" ";
}
std::cout<< std::endl;
}
}
感谢您的帮助。