C++连接AUPS-A10-R11的/dev/ttyUSB端口失败,需先通过screen连接
问题分析与解决方案
这种情况我之前处理过类似的串口通信问题,核心原因是你的C++代码没有完全配置好串口的通信参数,而screen工具在连接串口时会自动设置符合设备要求的串口属性,关闭screen后这些属性会保留在串口设备上,所以后续你的代码就能正常通信;但主机重启后,串口会恢复到系统默认的参数,你的代码没做正确配置,就出现了通信卡住的情况。
具体可能缺失的串口配置项
通常串口通信需要匹配以下关键参数,screen默认会设置成8N1(8数据位、无奇偶校验、1停止位)+ 禁用流控制的组合,你可以检查代码里是否遗漏了这些:
- 数据位、停止位、奇偶校验:设备大概率要求8数据位、无奇偶校验、1停止位,你的代码可能只设置了波特率,没明确配置这几项。
- 流控制:多数工业USB转串口设备不需要硬件(RTS/CTS)或软件(XON/XOFF)流控制,
screen默认会禁用这些,但你的代码可能没显式关闭。 - 终端模式:比如禁用本地回显、关闭规范模式(Canonical Mode),否则串口会缓存数据直到收到换行符,导致你读取不到设备的即时响应。
修复代码的具体步骤
你需要在打开串口后,用termios结构体完善串口配置,下面是关键的配置代码片段(可以加到你的串口初始化逻辑里):
#include <termios.h> #include <fcntl.h> int configure_serial(int fd) { struct termios tty; memset(&tty, 0, sizeof tty); // 获取当前串口属性 if (tcgetattr(fd, &tty) != 0) { perror("tcgetattr failed"); return -1; } // 设置波特率 cfsetospeed(&tty, B9600); cfsetispeed(&tty, B9600); // 配置数据位、停止位、奇偶校验:8N1 tty.c_cflag &= ~PARENB; // 无奇偶校验 tty.c_cflag &= ~CSTOPB; // 1停止位 tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; // 8数据位 // 禁用流控制 tty.c_cflag &= ~CRTSCTS; // 禁用硬件流控制 tty.c_iflag &= ~(IXON | IXOFF | IXANY); // 禁用软件流控制 // 禁用规范模式、本地回显等 tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 设置原始输入输出模式 tty.c_oflag &= ~OPOST; // 设置读取超时:比如等待1秒,最少读取1个字节 tty.c_cc[VMIN] = 1; tty.c_cc[VTIME] = 10; // 应用配置 if (tcsetattr(fd, TCSANOW, &tty) != 0) { perror("tcsetattr failed"); return -1; } return 0; }
调用这个函数时,要在打开串口之后:
int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror("Failed to open serial port"); return 1; } // 配置串口 if (configure_serial(fd) == -1) { close(fd); return 1; }
为什么screen操作后会正常?
screen在打开/dev/ttyUSB0时,会自动将串口配置为适合终端通信的参数(刚好匹配你的UPS设备要求),当你关闭screen时,串口的这些配置不会被重置(除非设备被重新枚举,比如重启主机),所以你的代码后续打开串口时,会继承这些正确的参数,自然就能通信了。
把上述配置补充到你的代码里,重启主机后再测试,应该就能解决卡在"Read Nothing"的问题了。
内容的提问来源于stack exchange,提问作者smily03
相关产品推荐
相关产品推荐

