最近帮朋友做一款工具,设计到对操作系统串口的操作,虽然这个东西已经是历史产物了,但是还有很多设备再用,索性从网络上找了一些代码最终完成这个小功能。下面资料将介绍串口在打开、关闭、读和写的时候一些注意事项以及参数的配置(代码中有详细注释。)
串口的开关
在串口打开的时候,我们要对串口做一些基础的初始化,比如波特率、数据位、校验位、停止位几个参数,他们分别被声明在 WinBase.h
头文件中。 打开串口的代码如下:
1 | bool SerialPortManager::Open(ReceiveDataCallback cb/* = nullptr*/) |
其中除了打开串口时传递的参数外,还包含了一些串口处理数据超时、读写缓冲区大小等属性,需要用到的根据自己的环境来配置。 串口的关闭很简单,只需要关闭掉 CreateFile 返回的句柄就可以了,这里不多介绍。
串口读写
串口的读写可以同步也可以异步,但是同步方式会造成一个问题就是当你调用了 ReadFile
在等待串口数据时,再去调用 WriteFile
就会被阻塞,因为 ReadFile
一直没有返回。所以我还是推荐大家用异步方式来读写串口,代码如下:
1 | void SerialPortManager::ReadSerialPortThread() |
1 | bool SerialPortManager::WriteData(const std::string& data) |
读因为是异步操作,我们需要传一个 OVERLAPPED
结构体到 ReadFile
的最后一个参数。写也是一样,我们可以用 GetOverlappedResult
或 WaitForSingleObject
来等待操作事件完成(记得要初始化 OVERLAPPED
否则会报错的)。两种方式读写我都做了演示,可以根据自己的需求改造。 读写操作的时候可以获取当前返回值判断是不是 ERROR_IO_PENDING
来确定是不是有数据还没有读取完成。
总结
串口的读写其实还是相对简单的,上面代码基本上把可能出现问题的点都体现出来了,最后再来罗列一下注意事项。
- 打开串口时要根据硬件情况初始化串口参数(在 WinBase.h 中有声明)
- 设置串口的缓冲区和超时
- 异步去读写串口通过返回值判断是否读写成功
- 不要忘记初始化 OVERLAPPAD 结构
- 读取完成后 PurgeComm 串口