【发布时间】:2018-12-24 14:07:49
【问题描述】:
我一直在尝试使用 USB 到串行转换器从连接到我的树莓派的串行温度传感器读取响应。
我可以看到对传感器设备的写入似乎有效。但是,当我尝试从串行芯片回读时,读取失败并显示 -1。
我确实尝试使用 realterm 程序使用相同的波特率 9600 8 位无奇偶校验设置,并且能够按预期读取和写入十六进制值,请指出正确的方向。
void serial_write(char parameter,char value) {
int fd;
uint8_t bytes_wr;
char wr_buffer[3];
fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
ERROR("Error! in Opening ttyUSB0 \n");
else
DEBUG("ttyUSB0 Opened Successfully \n");
struct termios SerialPortSettings;
tcgetattr(fd, &SerialPortSettings);
cfsetispeed(&SerialPortSettings,B9600);
cfsetospeed(&SerialPortSettings,B9600);
SerialPortSettings.c_cflag &= ~PARENB;
SerialPortSettings.c_cflag &= ~CSTOPB;
SerialPortSettings.c_cflag &= ~CSIZE;
SerialPortSettings.c_cflag |= CS8;
SerialPortSettings.c_cflag &= ~CRTSCTS;
SerialPortSettings.c_cflag |= CREAD | CLOCAL;
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
SerialPortSettings.c_oflag &= ~OPOST;
if ((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0)
ERROR("ERROR ! in Setting attributes \n");
else
DEBUG("BaudRate=9600\tStopBits=1\tParity=none \n");
wr_buffer[0] = write;
wr_buffer[1] = parameter;
wr_buffer[2] = value;
bytes_wr = write(fd, wr_buffer,sizeof(wr_buffer));
DEBUG("Total Bytes written: %d \n", sizeof(wr_buffer));
close(fd);
}
上述函数似乎按预期写入串行端口,但是当我尝试读取时,读取失败并显示 -1
char serial_read(char parameter) {
int fd, read_length, i;
uint8_t bytes_wr;
char wr_buffer[2];
fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
ERROR("Error! in Opening ttyUSB0 \n");
else
DEBUG("ttyUSB0 Opened Successfully \n");
struct termios SerialPortSettings;
tcgetattr(fd, &SerialPortSettings);
cfsetispeed(&SerialPortSettings,B9600);
cfsetospeed(&SerialPortSettings,B9600);
SerialPortSettings.c_cflag &= ~PARENB;
SerialPortSettings.c_cflag &= ~CSTOPB;
SerialPortSettings.c_cflag &= ~CSIZE;
SerialPortSettings.c_cflag |= CS8;
SerialPortSettings.c_cflag &= ~CRTSCTS;
SerialPortSettings.c_cflag |= CREAD | CLOCAL;
SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);
SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
SerialPortSettings.c_oflag &= ~OPOST;
if ((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0)
ERROR("ERROR ! in Setting attributes \n");
else
DEBUG("BaudRate=9600\tStopBits=1\tParity= none\n");
wr_buffer[0] = read;
wr_buffer[1] = parameter;
bytes_wr = write(fd, wr_buffer,sizeof(wr_buffer));
DEBUG("Total Bytes written: %d \n", sizeof(wr_buffer));
usleep(8000);
tcflush(fd,TCIFLUSH);
char rd_buffer[4];
read_length = read(fd, rd_buffer,sizeof(rd_buffer));
DEBUG("Total bytes read = %d \n",read_length);
for (i==0;i<read_length;i++){
DEBUG("rd_buffer[%d]=%x \n",i,rd_buffer[i]);
}
close(fd);
return rd_buffer[0];
}
使用 realterm windows 应用程序,所有写入和读取似乎都可以正常工作。
【问题讨论】:
-
为什么要睡觉?为什么选择 tcflush? '返回 rd_buffer;' - 不,返回本地数组是 UB
-
嗨对不起我的实际程序返回 rd_buffer[0] 。我试图删除 tcflush 以删除缓冲区中存储的先前数据。我最初没有睡觉,但我看到了一些例子,他们说我们必须等待数据写入才能读取。
-
您的代码有错误(因为您从不良示例中复制)。您的 termios 初始化不正确且不完整;请参阅stackoverflow.com/questions/51195829/… 您使用 tcflush() 而不是 tcdrain() 是有问题的。您选择的非阻塞 I/O 处理不当。如果您不了解要求,请使用阻塞 I/O。
标签: c linux raspberry-pi serial-port termios