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

我正在尝试学习如何使用C对Linux中的ttyS0串口进行编程。我的另一台机器连接到我的串口,每隔两秒钟发送5f和6f的交替hex值。 我已经与其他端口监控应用程序validation了这些值是否出现在端口上。 在我的代码中,我使用阻塞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  #include  #include  #include  #include  #include  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); } 

尝试设置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设置并在离开程序之前恢复它们也是明智之举。