我一直试图通过/dev/ttyS设备在linux上执行串行通信,但当我在写入后尝试从中读取时,我没有读取任何数据。
我有以下代码
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
int main() {
printf("hello worldn");
int n;
int fd;
char c;
int bytes;
char buffer[10];
char *bufptr;
int nbytes;
int tries;
int x;
struct termios options;
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY);
if(fd == -1) {
perror("open_port: Unable to open:");
} else
tcgetattr(fd, &options);
// Set the baudrate, same speed for both I/O
cfsetispeed(&options, B150);
cfsetospeed(&options, B150);
// Enable reading
options.c_cflag |= (CLOCAL | CREAD);
// Set 'RAW' mode
cfmakeraw(&options);
// Set byte size
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// Set parity
// options.c_cflag &= ~PARENB;
options.c_cflag |= PARENB;
options.c_cflag |= PARODD;
options.c_cflag &= ~CSTOPB;
// Set StopBits, @Linux no OneHalf is supproted, so OneHalf and Two are the same
options.c_cflag &= ~CSTOPB;
// Set Handshake options
// options.c_iflag |= CRTSCTS;
// options.c_iflag &= ~CRTSCTS;
// options.c_cflag &= ~( IXON | IXOFF | IXANY );
options.c_cflag |= IXON | IXOFF | IXANY;
// Set Timeouts
options.c_cc[VMIN] = 0; // read() will return after receiving character
options.c_cc[VTIME] = 10; // == 0 - infinite timeout, != 0 - sets timeout in deciseconds
tcsetattr(fd, TCSANOW, &options);
tcflush(fd, TCIOFLUSH);
bytes = write(fd, "ATZr",4);
printf(" wrote %d bytesn", bytes);
bufptr = buffer;
bytes = read(fd, bufptr, sizeof(buffer));
printf("number of bytes read is %dn", bytes);
perror ("read error:");
for (x = 0; x < 10 ; x++) {
c = buffer[x];
printf("%d ",c);
}
tcflush(fd, TCIOFLUSH);
close(fd);
printf("n");
return (0);
}
程序输出如下
hello world
wrote 4 bytes
number of bytes read is 0
read error:: Success
0 0 0 0 0 0 0 0 0 0
虽然我希望它能读取我刚刚写的4个字符,但读起来似乎是0字节。如果我将VTIME设置为0,则永远读取块。我试过做echo /dev/ttyS0
,但没有输出。你知道是什么原因造成的吗?如何解决?
您的代码显然是正常的,除了以下事实:
-
您在调用
printf(3)
之后调用perror("read error");
,而不是在read(2)
之后立即调用,因此可能的错误(如果发生(会被对printf(3)
的调用屏蔽为对read(2)
的调用。如果要打印读取的字符数,请在调用printf(3)
之前保存errno
的值和read(2)
的返回值,然后,如果返回的错误为neg,则调用perror(3)
。 -
不管怎样。
c_cc[VTIME] = 10
强制执行1秒超时,这对于重置调制解调器来说太过了。您的线路设置为:CS8, Parity ODD, one STOP bit, and 150 baudrate
通常情况下,调制解调器在重置后会响应
ATZr
命令,这需要一些时间(通常超过一秒钟(并且以默认调制解调器速度(因为您已经重置了它(和而不是以发送AT
命令的速度因此,重置调制解调器通常是盲目进行的,然后您发送一个简单的
ATr
命令,以请求rnOKrn
响应。对ATr
命令的响应通常是立即的,而不是对重置命令的响应,并允许调制解调器根据接收到的字符调整其通信设置。当接收到
A
和T
序列时,调制解调器总是通过对以高采样频率接收到的方脉冲进行采样来调整其速度,然后将速度切换到检测到的,并通常进行速度转换(使其能够以与远程协商不同的速度与调制解调器通话(