串口控件使用文档
为什么要重新做串口控件?传统串口的6大痛点
- 数据分片,拼帧麻烦:串口本质是字节流,不保证帧边界。低性能设备、USB转串口经常把一帧数据拆成3~5次返回,上层需要自己写拼帧逻辑,新手极易踩坑。
- 驱动缓冲大,延迟高:默认串口驱动缓冲时间长达几十毫秒,数据到达后不会立刻上报,通讯周期被无端拉长,高频场景性能差。
- 手动开关,容易出错:需要手动调用 Open/Close,初始化、修改参数时经常忘记重启,导致通讯失败。
- 拔插失效,人工重启:USB转串口设备拔掉重插后,原有句柄直接失效,程序不会自动恢复,必须手动重启软件。
- 参数修改繁琐:运行中修改波特率、校验位等参数,必须先关闭再打开,步骤多,容易遗漏。
- 格式死板,不符合习惯:只支持 COM1、COM2 这种英文格式,不兼容国内常用的「串口1」、纯数字等写法。
PCHMI 串口控件的核心优势
- 智能帧聚合:内置动态帧延时算法,自动根据波特率和数据量计算等待时间,分片数据自动聚合成完整帧返回,上层无需处理拼帧。
- 1ms级低延迟:底层驱动级1ms间隔超时优化,数据到达立即触发,比传统串口快5~10倍,适合高频通讯场景。
- 配置即生效:设置有效端口名自动打开串口,修改任意参数自动重启应用,无需手动开关。
- 自动重连恢复:内置USB设备拔插检测,设备意外断开后自动重试,插回后自动恢复通讯,全程无需人工干预。
- 全中文接口:属性、方法、事件全部中文命名,符合国内工程师使用习惯,无需记忆英文术语。
- 多格式端口名:支持 COM1、串口1、纯数字 三种写法,内部自动识别转换,兼容各种使用习惯。
串口控件是PCHMI内置的纯自研串口组件,零第三方依赖,直接调用 Win32 底层 API 控制串口硬件。
适合 PLC 上位机通讯、扫描枪、传感器、Modbus RTU 等工控场景。
连接、重连、缓存、帧聚合全部由控件内部自动处理,业务代码只需配置参数、收发数据。
端口名兼容格式:三种写法自动识别转换:"COM1"、"串口1"、"1"。
1、基本概念
- 自动运行:设置有效端口名后自动打开串口,无需手动调用打开/关闭方法。
- 参数自动生效:运行中修改波特率、校验位等任何配置,控件自动重启应用新参数。
- 端口名:串口设备名称,支持 COM3、串口3、3 三种格式,内部自动转换。
- 波特率:通讯速率,常用 9600、19200、115200,支持任意标准波特率。
- 数据位:单字节数据长度,支持 5~8 位,工业场景默认 8 位。
- 校验位:数据校验方式,支持无、奇、偶、标记、空格五种,默认无校验。
- 停止位:帧结束标志位,支持 1 位、1.5 位、2 位,默认 1 位。
- 额外帧延时:帧聚合功能的核心参数。在数据理论传输时间基础上额外等待的时间,用于聚合分片数据。设为0则关闭聚合,数据立即透传。
- 自动重连:内置 USB 设备拔插检测,设备意外断开后自动重试,恢复后自动继续通讯。
- 低延迟读取:驱动层 1ms 间隔超时,数据到达立即回调,无多余等待。
2、API 接口说明
2.1 核心属性
| 属性名称 |
作用说明 |
| 端口名 |
串口设备名称,支持 COM1 / 串口1 / 1 三种格式,设置有效值自动打开串口 |
| 波特率 |
通讯波特率,修改后自动重启生效 |
| 数据位 |
数据位长度 5~8,默认 8,修改后自动重启生效 |
| 校验位 |
校验方式:无/奇/偶/标记/空格,修改后自动重启生效 |
| 停止位 |
停止位格式:一位/一点五位/两位,修改后自动重启生效 |
| 额外帧延时 |
帧聚合额外等待时间(毫秒)。0=关闭聚合,数据立即触发;>0=开启智能帧聚合 |
| 是否已打开 |
只读属性,获取当前串口是否处于打开状态 |
2.2 核心方法
| 方法名称 |
作用说明 |
| 发送字节(byte[]) |
向串口发送原始字节数组 |
| 发送字符串(string) |
向串口发送 ASCII 编码字符串 |
| 获取可用端口() |
静态方法,获取本机所有可用串口名称数组 |
| 计算推荐帧延时() |
根据当前配置计算标准3.5字符帧间隔,作为帧延时设置参考 |
2.3 核心事件
| 事件名称 |
触发说明 |
| 收到数据(byte[]) |
收到完整数据帧时触发,后台线程执行,更新 UI 需使用 Invoke |
3、最简单收发示例(直接复制使用)
// 实例化控件,配置参数自动打开
串口 sp = new 串口();
sp.端口名 = "COM4";
sp.波特率 = 115200;
sp.校验位 = 校验方式.无;
sp.数据位 = 8;
sp.停止位 = 停止位格式.一位;
// 订阅接收事件
sp.收到数据 += data =>
{
// 后台线程,更新界面请用 Invoke
Console.WriteLine("收到数据:" + BitConverter.ToString(data));
};
// 直接发送数据,无需手动打开
sp.发送字节(new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x02 });
执行效果:
- 设置端口名后自动打开串口,进入接收等待状态
- 收到数据立即触发
收到数据 事件,延迟毫秒级
- USB 设备意外拔掉自动重试,插回后自动恢复通讯
- 运行中修改任意参数,控件自动重启应用新配置
4、智能帧聚合示例(解决数据分片)
串口 sp = new 串口();
sp.端口名 = "串口2";
sp.波特率 = 9600;
// 开启帧聚合:额外延时2ms,自动聚合分片数据
// 控件会根据当前收到的数据量自动计算基础传输时间,加上2ms余量
sp.额外帧延时 = 2;
// 也可以直接使用推荐值(标准3.5字符帧间隔)
// sp.额外帧延时 = sp.计算推荐帧延时();
sp.收到数据 += data =>
{
// 这里收到的就是完整的一帧数据,无需自己拼帧
Console.WriteLine("完整帧:" + BitConverter.ToString(data));
};
5、扫描枪/传感器只读示例
串口 scanPort = new 串口();
scanPort.端口名 = "1"; // 支持纯数字格式
scanPort.波特率 = 9600;
scanPort.额外帧延时 = 5; // 聚合扫描枪分片数据
scanPort.收到数据 += data =>
{
string code = System.Text.Encoding.ASCII.GetString(data);
Console.WriteLine("扫描到条码:" + code);
};
// 无需调用打开,配置完成自动进入接收状态
6、修改参数自动生效示例
串口 sp = new 串口();
sp.端口名 = "COM3";
sp.波特率 = 9600;
// 运行中直接修改参数,控件自动重启应用新配置
sp.波特率 = 115200;
sp.校验位 = 校验方式.偶;
// 修改完成立即按新参数通讯
sp.发送字符串("HELLO");
6、重要注意事项
- 自动运行:设置有效端口名自动打开,清空端口名自动关闭,无需手动调用开关方法。
- 线程说明:
收到数据 事件在后台读取线程触发,更新窗体 UI 控件必须使用 Invoke 切换到主线程。
- 帧聚合说明:额外帧延时设为0时完全透传,延迟最低;大于0时开启聚合,适合数据分片的设备,延时值建议设为1~5ms。
- 系统支持:底层基于 Win32 API,仅支持 Windows 系统,适合工控机、Windows 平台上位机。
- 自动重连:默认开启,设备断开后按 500ms 间隔自动重试,恢复后自动继续接收数据。
- 文件占用:同一个串口不能同时被多个程序打开,否则自动打开失败。
- USB 转串口:推荐使用 CH340、CP2102、FT232 等主流芯片,兼容性和稳定性更优。
- 设计模式:Visual Studio 设计器中不会实际打开串口,仅保存配置,运行程序后自动生效。