我一直在尝试通过/ 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 world\n");
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, "ATZ\r",4);
printf(" wrote %d bytes\n", bytes);
bufptr = buffer;
bytes = read(fd, bufptr, sizeof(buffer));
printf("number of bytes read is %d\n", 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
,但是没有输出。知道是什么原因导致的,如何解决?
答案 0 :(得分:0)
您的代码显然可以,但以下事实除外:
您在致电perror("read error");
之后致电printf(3)
,而不是在read(2)
之后致电,因此可能的错误(如果发生)被屏蔽通过调用read(2)
到printf(3)
。如果要打印读取的字符数,请在调用errno
之前保存read(2)
的值和printf(3)
的返回值,然后,如果返回的错误为neg,则调用perror(3)
。
无论如何。 c_cc[VTIME] = 10
造成一秒超时,这对于重置调制解调器来说太过分了。您的行设置为:
CS8, Parity ODD, one STOP bit, and 150 baudrate
通常,调制解调器在重置后回答ATZ\r
命令 ,这会花费一些时间(通常超过一秒钟),并且会花费默认的调制解调器速度(因为您已将其重置)并且不是以发送AT
命令的速度。
因此,重置调制解调器通常是盲目的完成的,然后您发送一个简单的AT\r
命令,以请求\r\nOK\r\n
响应。 AT\r
命令的答案通常是立即的,而不是对reset命令的响应,它使调制解调器根据收到的字符调整其通信设置。
调制解调器在接收到A
和T
序列时,始终会调整其速度,方法是通过以高采样频率对接收到的方波脉冲进行采样,然后将速度切换到检测到的速度并正常进行速度转换(从而可以以不同于远程协商的速度与调制解调器通话)