API异步串口读写可通过非阻塞模式或事件驱动实现高效
API 异步串口读写详解
异步串口通信概念
什么是异步通信?
异步通信是指数据以不定时的突发形式传输,通信双方通过起始位和停止位同步时钟,与同步通信相比,异步通信无需共享时钟信号,但需要协商通信参数(如波特率)。

异步 vs 同步
| 特性 | 异步通信 | 同步通信 |
|---|---|---|
| 时钟信号 | 内嵌在数据流中 | 需要独立时钟线 |
| 数据格式 | 起始位+数据位+校验位+停止位 | 固定帧结构 |
| 适用场景 | 低速率、短距离设备 | 高速率、长距离传输 |
| 典型协议 | UART、RS232/485 | SPI、I²C、USB |
异步串口读写流程
串口初始化
关键参数配置表
| 参数 | 说明 | 典型值 |
|---|---|---|
| 波特率 | 每秒传输位数(bps) | 9600, 115200 |
| 数据位 | 每个字节的有效位数 | 8位 |
| 停止位 | 数据结尾的空闲位数 | 1位 |
| 校验位 | 错误检测方式(None/Odd/Even) | None |
| 流控 | 硬件/软件流控 | CTS/RTS |
初始化步骤(以Windows API为例):
- 调用
CreateFile()打开串口设备(如COM3) - 使用
DCB结构体配置参数(BuildCommDCB) - 设置超时时间(
SetCommTimeouts) - 创建事件对象用于异步通知(
CreateEvent)
异步读写实现方式
Windows API 实现(重叠 I/O)
核心函数与结构
| 函数/结构 | 作用 |
|---|---|
CreateFile |
打开串口设备,返回句柄 |
OVERLAPPED |
异步操作结构体,包含事件句柄和内部状态 |
ReadFile |
异步读取数据(需配合 OVERLAPPED) |
WriteFile |
异步写入数据(需配合 OVERLAPPED) |
GetOverlappedResult |
获取异步操作结果(可同步等待或直接查询) |
示例代码框架
HANDLE hSerial = CreateFile(L"COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
DCB dcb = {0};
BuildCommDCB(L"9600,N,8,1", &dcb);
SetCommState(hSerial, &dcb);
OVERLAPPED osReader = {0};
osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
char buffer[1024];
DWORD bytesRead;
ReadFile(hSerial, buffer, sizeof(buffer), &bytesRead, &osReader);
// 等待完成或处理其他任务
WaitForSingleObject(osReader.hEvent, INFINITE);
跨平台实现方案
Boost.Asio 库
核心类与功能
| 类/函数 | 功能 |
|---|---|
io_service |
异步事件调度器 |
serial_port |
串口封装类(构造时配置参数) |
async_read |
异步读取(需指定回调函数) |
async_write |
异步写入(需指定回调函数) |
示例代码
boost::asio::io_service io;
boost::asio::serial_port serial(io, "COM3");
serial.set_option(boost::asio::serial_port_base::baud_rate(9600));
char buffer[1024];
serial.async_read_some(boost::asio::buffer(buffer),
[&](const boost::system::error_code& ec, std::size_t length) {
if (!ec) {
// 处理接收到的数据
}
});
io.run();
常见问题与解决方案
数据丢失问题
- 原因:缓冲区溢出或读写速度不匹配
- 解决方案:
- 增大接收缓冲区大小
- 使用流量控制(RTS/CTS)
- 优化数据处理逻辑(如分片处理)
异步操作死锁
- 原因:未正确处理事件对象或回调函数阻塞
- 解决方案:
- 确保回调函数简短高效
- 使用线程池处理复杂逻辑
- 避免在异步回调中再次调用阻塞API
相关问题与解答
Q1:如何判断异步读写是否完成?
A:
- Windows API:通过
OVERLAPPED结构中的事件对象(hEvent)判断,调用WaitForSingleObject或GetOverlappedResult检查状态。 - Boost.Asio:通过回调函数或
io_service的事件循环机制自动通知完成。 - POSIX:使用
select或poll监听文件描述符状态。
Q2:异步读写时如何保证数据完整性?
A:

- 协议设计:添加帧头、校验和(如CRC)或固定长度标识。
- 缓冲区管理:使用环形缓冲区或分段处理数据。
- 流量控制:启用硬件流控(如RTS/CTS)或软件流控(如XON/XOFF)。
- 超时机制:设置合理的读写超时
各位小伙伴们,我刚刚为大家分享了有关“api 异步串口读写”的知识,希望对你们有所帮助。如果您还有其他相关问题需要解决,欢迎随时提出哦!
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!