API异步串口通信基于非阻塞机制,通过事件驱动与回调实现并行数据传输,提升效率,适用于实时及高并发
API 异步串口通信详解
异步串口通信基础
核心概念
特性 | 说明 |
---|---|
非同步传输 | 无统一时钟信号,通过起始位和停止位实现同步 |
数据帧结构 | 起始位(1b) + 数据位(5-9b) + 校验位(可选) + 停止位(1-2b) |
波特率 | 每秒传输的比特数(常见值:9600、115200等) |
硬件流控制 | 通过RTS/CTS或DTR/DSR实现流量控制(可选) |
关键参数配置表
参数名称 | 说明 | 典型值 |
---|---|---|
波特率 | 传输速率 | 9600 |
数据位 | 有效数据位数 | 8位 |
停止位 | 结束标志位数 | 1位 |
奇偶校验 | 错误检测方式 | 无校验(None) |
缓冲区大小 | 收发数据缓存容量 | 1024字节(可配置) |
API 实现流程
Windows 平台实现步骤
(1) 初始化串口
HANDLE hSerial = CreateFile(
"\.COM3", // 串口编号
GENERIC_READ | GENERIC_WRITE, // 读写权限
0, // 独占访问
NULL, // 默认安全属性
OPEN_EXISTING, // 必须存在
0, // 同步模式
NULL // 模板句柄
);
(2) 配置串口参数
DCB dcb = {0};
dcb.DCBlength = sizeof(dcb);
GetCommState(hSerial, &dcb); // 获取当前配置
// 修改参数
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8; // 数据位
dcb.Parity = NOPARITY; // 无校验
dcb.StopBits = ONESTOP; // 1停止位
SetCommState(hSerial, &dcb); // 应用配置
(3) 数据收发操作
发送数据
DWORD bytesWritten;
BYTE buffer[] = "Hello Serial";
WriteFile(hSerial, buffer, sizeof(buffer), &bytesWritten, NULL);
接收数据
DWORD bytesRead;
BYTE recvBuffer[1024] = {0};
ReadFile(hSerial, recvBuffer, sizeof(recvBuffer), &bytesRead, NULL);
(4) 关闭串口
CloseHandle(hSerial);
Linux 平台实现对比
平台特征 | Windows | Linux |
---|---|---|
设备文件路径 | \.COM3 | /dev/ttyS3 |
配置接口 | DCB 结构体 | termios 结构体 |
文件描述符操作 | HANDLE 句柄 | int fd 文件描述符 |
完整示例代码(Windows)
#include <windows.h>
#include <stdio.h>
int main() {
// 1. 打开串口
HANDLE hSerial = CreateFile(
"\.COM3",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hSerial == INVALID_HANDLE_VALUE) {
printf("Error: %d
", GetLastError());
return 1;
}
// 2. 配置参数
DCB dcb;
dcb.DCBlength = sizeof(dcb);
GetCommState(hSerial, &dcb);
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOP;
SetCommState(hSerial, &dcb);
// 3. 发送数据
BYTE sendData[] = "Test Data";
DWORD bytesWritten;
WriteFile(hSerial, sendData, sizeof(sendData), &bytesWritten, NULL);
// 4. 接收数据
BYTE recvBuffer[1024] = {0};
DWORD bytesRead;
ReadFile(hSerial, recvBuffer, sizeof(recvBuffer), &bytesRead, NULL);
printf("Received: %s
", recvBuffer);
// 5. 关闭串口
CloseHandle(hSerial);
return 0;
}
常见问题与解决方案
权限问题
现象:CreateFile
返回ERROR_ACCESS_DENIED
解决方案:
- 以管理员权限运行程序
- 检查设备管理器中的端口占用情况
- 在代码中添加
FILE_FLAG_OVERLAPPED
标志
数据丢失问题
原因分析:
- 接收缓冲区溢出
- 未及时处理接收事件
优化方案: - 启用
EV_RXCHAR
事件通知 - 设置合理的
CV_CTS
流控 - 使用重叠I/O模式(
OVERLAPPED
结构)
相关问题与解答
Q1:如何判断串口是否成功打开?
A:检查CreateFile
返回值是否为INVALID_HANDLE_VALUE
,若失败可通过GetLastError()
获取错误码,常见错误包括:
ERROR_FILE_NOT_FOUND
:端口号不存在ERROR_ACCESS_DENIED
:权限不足ERROR_OPERATION_ABORTED
:设备被占用
Q2:如何处理接收缓冲区的粘包问题?
A:通过以下方式解决:
- 定界符协议:在数据包末尾添加特殊分隔符(如)
- 长度前缀协议:在数据前添加长度字段(如先发送4字节长度值)
- 固定数据包长度:约定每次发送
以上内容就是解答有关“api 异步串口通信”的详细内容了,我相信这篇文章可以为您解决一些疑惑,有任何问题欢迎留言反馈,谢谢阅读。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复