写入/ dev / ttyS0后读取0个字节

时间:2019-10-24 08:21:01

标签: c++ c linux serial-port tty

我一直在尝试通过/ 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,但是没有输出。知道是什么原因导致的,如何解决?

1 个答案:

答案 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命令的响应,它使调制解调器根据收到的字符调整其通信设置。

    调制解调器在接收到AT序列时,始终会调整其速度,方法是通过以高采样频率对接收到的方波脉冲进行采样,然后将速度切换到检测到的速度并正常进行速度转换(从而可以以不同于远程协商的速度与调制解调器通话)