windows下用createfile打开com口需用“\.\comx”格式(x≥10时必加前缀),设generic_read|generic_write与open_existing;再调setcommstate配置dcb参数(如cbr_9600、8数据位、noparity、onestopbit),并用setcommtimeouts设读超时防阻塞。

Windows 下用 CreateFile 打开 COM 口并配置串口参数
Windows 没有标准 C++ 接口枚举串口,得靠系统 API。先用 QueryDosDevice 或遍历 COM1 到 COM255 来找可用端口——实际中多数设备在 COM1–COM9,但 Win10/11 的 USB 转串口可能到 COM20+,硬写死上限会漏设备。
打开后必须调用 SetCommState 配置 DCB 结构体,重点设这几个字段:
-
BaudRate:常见如CBR_9600、115200(直接填数字也行) -
ByteSize:通常为8 -
StopBits:常用ONESTOPBIT或TWOSTOPBITS -
Parity:多数无校验,设为NOPARITY -
fRtsControl和fDtrControl:按设备手册决定是否启用 RTS/DTR
漏设 DCB 或没调 SetCommState 会导致读写失败,错误码常是 ERROR_INVALID_PARAMETER。
用 ReadFile 和 WriteFile 收发原始字节流
串口默认是阻塞 I/O,但直接阻塞读容易卡死——比如对方没发数据,ReadFile 就一直等。更稳的做法是用 SetCommTimeouts 设超时:
ReadIntervalTimeout = 0-
ReadTotalTimeoutConstant = 100(单位毫秒) ReadTotalTimeoutMultiplier = 0
这样 ReadFile 最多等 100ms,有数据就读,没数据就返回 0 字节,不卡主线程。
写数据注意:WriteFile 不保证一次写完全部缓冲区,返回值是实际写入字节数,需循环调用直到写完;读同理,ReadFile 可能只读到部分帧,尤其高速通信时——你得自己缓存、拼包、按协议切分。
示例片段:
DWORD bytesWritten; WriteFile(hPort, buffer, len, &bytesWritten, nullptr); // 必须检查 bytesWritten 是否等于 len,否则要重试
Linux 下用 open + termios 配置和读写
Linux 把串口当文件,路径一般是 /dev/ttyS0(板载)、/dev/ttyUSB0(USB 转串口)、/dev/ttyACM0(Arduino 类)。先用 opendir("/dev") 扫描含 tty 的设备名,或直接尝试常见路径。
关键在 tcgetattr / tcsetattr 配置 termios:
- 关掉规范模式:
c_lflag &= ~(ICANON | ECHO | ISIG) - 关掉输入处理:
c_iflag &= ~(IXON | IXOFF | IGNCR | ICRNL) - 设波特率用
cfsetispeed(&tty, B115200)和cfsetospeed - 确保
c_cflag |= CREAD | CLOCAL(允许读 + 不控制 modem)
漏关 ICANON 会导致 read() 等换行才返回,根本收不到原始字节流;漏清 IXON 可能让 XON/XOFF 流控字符被内核吃掉。
读写直接用 read() / write(),但记得设 O_NONBLOCK 或用 select() 监听可读事件,否则阻塞行为和 Windows 一样难控。
跨平台收发原始字节流的几个硬坑
串口不是 TCP,没有连接概念,也没有自动重传或粘包处理。所有“帧”都得你自己定义边界:
- 别依赖
ReadFile或read()一次返回一整条命令——它只按当前缓冲区状态返回,可能是半包、两包拼一起、甚至单字节拆成多次返回 - Windows 下如果用
OVERLAPPED异步 I/O,必须配WaitForSingleObject或GetOverlappedResult,不能假设回调立刻执行 - Linux 下某些 USB 串口芯片(如 CH340)驱动有 16 字节隐式缓冲,
read()可能延迟返回,加tcflush(fd, TCIFLUSH)清空再读更可靠 - 权限问题:Linux 普通用户默认无权访问
/dev/tty*,得加进dialout组;Windows 上某些虚拟串口需要管理员权限才能打开
原始字节流的本质就是裸设备通信——没封装、没保障、没智能。你写的每一行读写逻辑,都得对应物理层的真实时序和设备协议。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











