C语言 编程 Linux 串行端口,ttyS0



我正在尝试学习如何使用C在Linux中编程ttyS0串行端口。 我有另一台机器连接到我的串行端口,大约每两秒发送一次 5f 和 6f 的交替十六进制值。 我已经通过其他端口监控应用程序验证了这些值是否出现在端口上。 在我的代码中,我在 10 个字符长度的缓冲区中使用阻塞 read()。 即使我的另一台机器仍在发送数据,read() 也会永远阻塞。 如果我包含行 fcntl(fd, F_SETFL, FNDELAY); 将 read() 设置为非阻塞 read() 总是返回值 -1,这意味着 UART 缓冲区中没有数据,而我的 for 循环代码只是打印出缓冲区中的随机值。 简而言之,我的假设是我的代码没有读取 ttyS0,我不知道为什么。 下面是我的代码,希望有人能看到导致我的问题的原因并纠正我。 顺便说一下,我使用的是Scientific Linux,我相信ttyS0是com端口1,就像在RedHat和Fedora中一样。下面是我运行代码时的输出。 它似乎没有问题地写入COM端口,但是对于读取,它说它不可用。 同样很明显,我打印出的缓冲区只是随机值,而不是已读入的数据。 谢谢

控制台输出

hello world
hi again
write error: : Success
 wrote 4 bytes
number of bytes read is -1
read error:: Resource temporarily unavailable
4  8  120  -99  -73  -65  41  -120  4  8  
should of put something out

法典

#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 | O_NDELAY);
    if(fd == -1)
    {
        perror("open_port: Unable to open:");
    }
    else
    {
        fcntl(fd, F_SETFL, 0);
        printf("hi againn");
    }
    tcgetattr(fd, &options);
    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_cflag &= ~( ICANON | ECHO | ECHOE |ISIG );
    options.c_iflag &= ~(IXON | IXOFF | IXANY );
    options.c_oflag &= ~OPOST;
    tcsetattr(fd, TCSANOW, &options);

    write(fd, "ATZr",4);
    printf(" wroten");
    bufptr = buffer;

    fcntl(fd, F_SETFL, FNDELAY);
     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);
    }
    close(fd);
    //puts(buffer[0]);
    printf("nshould of put something out n");
    return (0);
}

以下行将导致问题:

options.c_cflag &= CSTOPB;

它将重置c_cflag的所有其他位。

如果要使用 1 个停止位,请使用:

options.c_cflag &= ~CSTOPB;

如果要使用 2 个停止位,请使用:

options.c_cflag |= CSTOPB;

编辑:

以下行也会导致问题:

fcntl(fd, F_SETFL, 0);

它将重置几个重要的标志。

最新更新