可以写入,但无法从linux C程序中读取串口ttyS0

时间:2012-04-21 04:08:55

标签: c linux serial-port

我正在尝试学习如何使用C对Linux中的ttyS0串口进行编程。我的另一台机器连接到我的串口,大约每两秒发送5f和6f的交替十六进制值。我已经与其他端口监控应用程序验证了这些值是否出现在端口上。在我的代码中,我使用阻塞 read()到10个字符长度的缓冲区中。即使我的其他计算机仍在发送数据, 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 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 | O_NDELAY);
    if(fd == -1)
    {
        perror("open_port: Unable to open:");
    }
    else
    {
        fcntl(fd, F_SETFL, 0);
        printf("hi again\n");
    }

    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, "ATZ\r",4);
    printf(" wrote\n");
    bufptr = buffer;


    fcntl(fd, F_SETFL, FNDELAY);
     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);
    }
    close(fd);

    //puts(buffer[0]);
    printf("\nshould of put something out \n");

    return (0);
}

1 个答案:

答案 0 :(得分:0)

尝试设置MIN和/或TIME值:

/*...*/
options.c_cc[VMIN] = 1; //read() will return after receiving 1 character
options.c_cc[VTIME] = 0; // == 0 - infinite timeout, != 0 - sets timeout in deciseconds
/*...*/
tcsetattr(fd, TCSANOW, &options);

给定的示例将设置read()以在获取任何符号后返回并无限期地等待输入。当然,您可以根据需要使用这些参数(例如,如果需要,将MIN设置为10)。

您可能希望删除fcntl(fd, F_SETFL, FNDELAY);调用此功能。

保存以前的termios设置并在离开程序之前恢复它们也是明智的。