Windows下打开COM端口需用"\.COM3"格式,Linux下open串口后须清除ICRNL等终端标志;读取时应按实际字节数处理,避免字符串类截断0x00,保持数据原始性。

Windows下用CreateFile打开COM端口要加\.前缀
直接传"COM3"会失败,系统找不到设备。必须写成"\\.\COM3"(C++字符串里反斜杠要转义),否则CreateFile返回INVALID_HANDLE_VALUE,GetLastError()通常是ERROR_FILE_NOT_FOUND。
常见错误是抄网上代码时漏掉\.,或者在Qt里用QSerialPort却手动去调CreateFile——没必要,QSerialPort已封装好。
-
GENERIC_READ | GENERIC_WRITE必须同时指定,哪怕只读 -
FILE_ATTRIBUTE_NORMAL够用,别用FILE_FLAG_OVERLAPPED除非真做异步IO - 波特率、数据位等需用
SetCommState单独设置,CreateFile不处理这些
Linux下串口就是普通文件,但open()后必须关ICRNL和INPCK
默认终端属性会把
转成
、校验奇偶位、丢弃0x00——这不是你想要的“原始数据”。关键是要清掉c_iflag里的ICRNL、INPCK、ISTRIP、IXON等标志。
示例片段:
struct termios tty; tcgetattr(fd, &tty); tty.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON); tty.c_cflag |= CREAD | CLOCAL; cfsetispeed(&tty, B115200); cfsetospeed(&tty, B115200); tcsetattr(fd, TCSANOW, &tty);
- 别忘了
tcflush(fd, TCIOFLUSH)清缓冲区,尤其重连时旧数据还在 -
O_NOCTTY一定要加,否则可能被系统当成控制终端抢走stdin -
O_NONBLOCK慎用:没数据时read()直接返回-1,容易误判断连
read()返回值小于请求长度不等于出错
串口是慢速设备,read(fd, buf, 1024)返回32很常见——只要不是-1,就说明收到了32字节,不是失败。Linux下尤其明显,内核不会等满缓冲才返回。
Windows同理:ReadFile的lpNumberOfBytesRead可能远小于你传的nNumberOfBytesToRead,这是正常行为。
- 别用
while (read(...) > 0)狂读,会卡住或漏包;应设超时+单次读完立即处理 - Linux可用
select()或poll()判断可读,避免忙等 - Windows建议用
WaitCommEvent配合ReadFile,比轮询高效
二进制数据里含0x00时,千万别用std::string或CString存
所有以

