1. 项目概述与核心价值
最近在整理老项目资料时,翻出了一个用VC++6.0写的串口通信数据采集系统。虽然现在看这个开发环境有点“古董”,但它的核心思想、对Windows底层通信机制的理解,以及如何构建一个稳定可靠的数据采集框架,至今依然非常有价值。很多工业现场、实验室的老设备,其上位机软件依然是基于这套技术栈在稳定运行。这个项目完整地展示了如何使用经典的MSComm控件,结合多线程、数据解析和文件存储,打造一个从硬件信号到可视化数据的完整链路。
简单来说,这个系统就是一个桥梁。它的一端通过电脑的RS-232串口(也就是那个9针的COM口)连接着下位机,可能是单片机、PLC、传感器或者各种仪表。另一端则在电脑上实时显示接收到的数据,比如温度、压力、转速,并把它们保存下来供后续分析。它的核心价值在于 稳定、实时和可扩展 。在VC++6.0那个时代,没有那么多现成的高级框架,很多细节需要开发者亲手把控,这也恰恰是理解Windows编程和串口通信精髓的好机会。无论你是想维护遗留系统,还是想深入理解串口通信的底层原理,这个案例都能提供不少干货。
2. 系统整体设计与架构拆解
2.1 技术选型背后的考量
为什么是VC++6.0和MSComm控件?这得从当时的开发环境和需求说起。VC++6.0(Visual C++ 6.0)是上世纪90年代末到21世纪初Windows桌面开发的绝对主力,其附带的MFC(Microsoft Foundation Classes)框架极大地简化了Windows GUI程序的开发。对于需要直接操作硬件端口、追求高性能和稳定性的工业数据采集软件,C++结合MFC是不二之选。它生成的代码执行效率高,对系统资源掌控力强,而且最终发布就是一个独立的EXE文件,依赖项少,非常适合部署在工况复杂的工业现场。
串口通信部分,我们选择了MSComm(Microsoft Communications Control)这个ActiveX控件。现在看来,它可能不是最高效的方式,但在当时却是最快速、最稳定的方案之一。MSComm控件封装了Windows串口通信的核心API(主要是 CreateFile , ReadFile , WriteFile 等),提供了一个事件驱动的编程模型。你只需要在图形化界面中拖入这个控件,设置好端口号、波特率等参数,然后处理它发出的“收到数据”事件即可,大大降低了直接调用复杂API的门槛。相比于直接用API编写,MSComm控件更快上手,且经过大量项目验证,稳定性有保障。当然,它的缺点是不够灵活,有些底层参数无法精细调节,但在绝大多数标准RS-232通信场景下,它完全够用。
2.2 系统核心模块划分
整个系统可以清晰地划分为四个层次,这种分层设计保证了代码的清晰度和可维护性。
1. 用户界面层: 基于MFC的对话框应用程序。主界面包含连接/断开按钮、串口参数配置区(波特率、数据位、停止位、校验位)、数据接收显示框(通常使用 CRichEditCtrl 或 CListCtrl 控件以支持大量文本滚动显示)、数据发送输入框,以及开始/停止记录数据的按钮。界面设计的原则是直观,所有关键状态(如串口是否打开、数据是否在记录)都要有明确的视觉反馈。
2. 通信控制层: 这是系统的中枢,核心就是MSComm控件。它负责所有与串口硬件的交互。我们将其封装在一个独立的类(例如 CSerialPort )中,这个类处理控件的初始化、参数配置、打开关闭、数据发送,以及最重要的——响应 OnComm 事件。当串口有数据到达、发生错误或状态改变时,都会触发此事件。在这一层,我们只负责数据的原始字节流的接收和发送,不涉及任何业务逻辑解析。
3. 数据处理层: 这是将原始字节流转化为有意义信息的关键。从通信层接收到的是二进制数据缓冲区。处理层需要根据与下位机约定的 通信协议 来解析。例如,常见的协议格式可能是:“帧头(如0xAA)+ 数据长度 + 传感器数据(多个字节)+ 校验和(如累加和或CRC)+ 帧尾(如0x55)”。这一层需要实现协议解析算法,验证帧的完整性(校验和),并将解析出的有效数据(如一个浮点数温度值)传递给上层。同时,它也负责将上层要发送的命令,按照协议打包成字节流,交给通信层发送。
4. 数据持久层: 负责将处理后的有效数据保存下来。通常采用两种方式:一是实时追加写入到文本文件(如.csv格式)或二进制文件,便于后续用Excel或专业软件分析;二是根据需求写入数据库(当时多用Access或SQL Server)。这一层要考虑文件写入的效率、防止数据丢失(定时刷新缓冲区)以及文件管理(按日期或大小自动创建新文件)。
注意: 在VC++6.0环境下使用MSComm控件,需要确保系统注册了
MSCOMM32.OCX文件。通常需要手动执行regsvr32 MSCOMM32.OCX命令进行注册,否则在设计界面或运行时都会找不到这个控件。
3. 核心实现细节与实操要点
3.1 MSComm控件的关键属性与方法
要驾驭MSComm控件,必须吃透它的几个关键属性。这些属性直接在控件的属性页设置,或通过代码动态设置。
- CommPort: 设置串口号,如1表示COM1。 切记 ,在打开端口前设置。
- Settings: 一个字符串,一次性设置波特率、校验位、数据位、停止位。格式为
”波特率,校验位,数据位,停止位“,例如”9600,n,8,1“表示波特率9600、无校验、8位数据、1位停止位。这是最常用的标准配置。 - PortOpen: 布尔型属性。
TRUE打开串口,FALSE关闭串口。打开前必须确保参数已设置正确,且端口未被其他程序占用。 - InputMode: 决定读取数据的类型。
0 - comInputModeText(默认)以文本方式读取,控件会帮你做ANSI/Unicode转换,但处理二进制数据会出问题。1 - comInputModeBinary以二进制方式读取,这是我们采集原始数据必须设置的。 - RThreshold: 这是一个非常重要的属性。它设定一个阈值,当接收缓冲区中的字节数达到或超过该值时,就会触发
OnCo
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/weixin_28256233/article/details/162779112



