Linux下的串口编程

我想用电路板上的RS232端口与PC通信。 我知道我可以使用“dev / ttyS0”来达到这个目的。

我可以使用write()函数打开和写入数据到PC。 但问题是我无法从“dev / ttyS0”读取。 每次我使用阅读function,我得到“资源暂时不可用”。 你能告诉我如何解决这个问题吗?

这是我的代码:

#include <stdio.h> #include <string.h> #include <fcntl.h> #include <termios.h> #include <unistd.h> int main() { int n = 0, fd = 0, bytes = 0; char ch = 0; char buffer[10], *bufPtr; int nBytes = 0, tries = 0, x = 0; struct termios term; fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror("open"); return; } else { fcntl(fd, F_SETFL, 0); perror("Port"); } if (n = tcgetattr(fd, &term) == -1) { perror("tcgetattr"); return; } if (n = cfsetispeed(&term, B115200) == -1) { perror("cfsetispeed"); return; } if (n = cfsetospeed(&term, B115200) == -1) { perror("cfsetospeed"); return; } term.c_cflag |= (CLOCAL | CREAD); term.c_cflag &= ~PARENB; term.c_cflag &= ~CSTOPB; term.c_cflag &= ~CSIZE; term.c_cflag |= CS8; term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); term.c_iflag &= ~(IXON | IXOFF | IXANY); term.c_cflag &= ~CRTSCTS; term.c_oflag &= ~OPOST; if (n = tcsetattr(fd, TCSANOW, &term) == -1) { perror("tcsetattr"); return; } write(fd,"LINUX",5); perror("write"); fcntl(fd, F_SETFL, FNDELAY); perror("fcntl"); bytes = read(fd, buffer, sizeof(buffer)); perror("read"); printf("Bytes : %d and data: %s\n", bytes, buffer); } 

Solutions Collecting From Web of "Linux下的串口编程"

你的测试是什么? 您是否简化了RS232 DB9连接器的针脚2和针脚3?

否则,如果没有要读取的数据, read将始终返回-1。

这是你的代码应该使用O_NDELAY标志打开串行线。

要避免阅读,如果没有数据要读取,你可以使用选择在你的情况:

 struct timeval tv; fd_set rset; int retV; int timeout = 5000; // 5 seconds tv.tv_usec = (timeout * 1000) % 1000000; tv.tv_sec = timeout / 1000; FD_ZERO ( &rset ); FD_SET ( fd, &rset ); retV = select ( fd+1, &rset, NULL, NULL, &tv ); if( retV == 0 ) { // timeout stuff } else if( retV < 0 ) { // Error stuff. Read errno to see what happened } else { // read data } 

编辑

删除fcntl(fd, F_SETFL, FNDELAY); 如果你想正常的阻塞读取,取消设置该标志。

在你的代码中,你也假设read将返回所有发送的字符,但是不是这样。 read将返回可供阅读的字符。 这意味着如果您发送“LINUX”,则可以请求5次读取以读取所有发送的5个字符。

最后一件事

 printf("Bytes : %d and data: %s\n", bytes, buffer); 

是未定义行为,因为buffer不是以NULL结尾的字符串。 你可以解决它在接收到的字符上循环,并用%c格式打印它,或者用下面的代码终止你的缓冲区:

 if (bytes > 0) buffer[bytes] = '\0'; 

要么

 char stringToSend[] = "LINUX"; size_t len = strlen(stringToSend) +1 ; write(fd,"LINUX", len); perror("write"); size_t receivedBytes = 0; bytes = 0; while (receivedBytes<len) { bytes = read(fd, &buffer[receivedBytes], sizeof(buffer)-1); perror("read"); if (bytes > 0) receivedBytes += bytes; } printf("Bytes : %d and data: %s\n", receivedBytes, buffer);