一种用户友好的C++串口类设计

时间:2022-09-01 10:49:57

一种用户友好的C++串口类设计

摘要:串口通信在装、设备中的应用非常普遍,该文描述了一种基于ActiveX控件MSComm和MFC Library Regular DLL的C++串口类设计,通过精心设计的函数接口和消息机制,大大简化了串口编程。与直接使用MSComm控件相比,采用这种串口类进行编程能够有效的降低串口编程的难度,用户仅仅需要最低限度的关于串口的知识就能写出正常工作的串口程序。

关键词:ActiveX控件;MSComm; MFC Library Regular DLL;Mcomm;客户程序

中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2013)19-4392-03

串口通信由于成本低,操作方便,可靠性高,传输距离长,应用非常广泛。通过计算机上的串口可以很方便的对装、设备进行参数设置,与设备之间进行数据传输,所以设计具有操作串口功能的计算机程序是十分常见的编程任务。

1 目前Windows操作系统上进行串口编程的四种方法

1)使用微软C运行时库的I/O函数

可采用_inp,_inpw,_inpd,_outp,_outpw,_outpd等函数对串口操作,这些函数可直接对串口芯片进行操作。需要对串口硬件电路的工作原理和时序非常熟悉,才能正确使用它们进行串口的设置、读取以及写入的操作。

2)使用Windows API函数

可采用Windows API中的ReadFile,WriteFile,BuildComDCB,SetCommBreak,SetCommConfig等函数对串口操作。这些函数用法复杂,不易掌握,需要对Windows系统的文件以及设备管理深入了解才能正确使用。

3)采用第三方串口通信类

互联网上有一些源代码开放的第三方串口通信类,比如CSerialPort,cnComm等,采用特定的语言如C++语言编写,并且打包成类(class),内部通过调用Windows API实现对串口的操作。它们突出的优点在于函数接口简单明了,易于编程使用,缺点是仅能供该特定语言的程序员编程使用,而且质量良莠不全,需要认真测试和挑选。

4)使用MFC库附带的ActiveX控件MSComm

这是微软公司提供的用于串口通信控制的ActiveX控件(Microsoft Communication Control)。它支持编译期以图形化的方式来设置串口的属性,它还提供了53个成员函数接口,用户可以通过在程序中调用这些接口来设置串口的属性以及进行串口通信。

从表1中可以看出,编程难度和调试难度的正相关性比较大,这是因为使用的函数越低级,控制的粒度越细,编程和调试的难度和工作量越大。与第三方串口通信类相比,MSComm面向多种语言,所以使用MSComm控件进行编程的情况比较普遍。

然而对于刚刚接触串口编程的用户来说,使用MSComm控件也不容易。首先,该控件接口函数高达53个,短时间不容易弄清楚它们的用法;其次,该控件采用VARIANT类型的接口数据,这种数据结构比较复杂,不易掌握;第三,该控件产生的串口事件是用不同的无符号整数值表示,用户需要查找资料来确定该整数值表示的意义,不够直观。因此在MSComm的基础上进一步简化串口编程就成了本文设定的工作目标。

2 用户友好的串口DLL和C++串口类设计

2.1串口DLL的设计

MSComm控件相当稳定可靠,为本文的设计工作提供了一个稳固的基础。MSComm是一种ActiveX控件,必须将它放置在ActiveX容器中才能工作。对话框是常用的ActiveX容器。为此本文设计了一个对话框类CommCtnr,当在对话框类CommCtnr中插入MSComm控件时,Visual C++开发环境自动替MSComm控件生成类CMSComm,该文将CMSComm类的对象作为对话框类CommCtnr的数据成员。

用户可以直接将相关的.cpp和.h文件以及.rc资源文件拷贝到自己的工程目录下,但这种方式显然很不方便。更好的办法是将相关的文件独立编译成一个动态链接库(DLL, Dinamic Link Library),用户只需要调用这个动态链接库就可以进行串口操作。MFC(Microsoft Foundation Class Library)支持两种动态链接库,一种是MFC Library Extension DLL,一种是MFC Library Regular DLL。前者能够将整个C++类作为DLL的外部接口,这样减少了DLL实现的困难,然而要求客户程序使用C++语言编写,并且动态链接MFC库才能够调用这种DLL,这样就大大缩小了它可能的用户群,所以本文不采用这种方式。第二种方式是使用MFC Library Regular DLL方式,这种DLL可供多种编程语言设计的客户程序使用。由于它对外界的接口只允许是C风格的函数,因此它不能接受类(class)类型的参数。为此本文设计每个C风格函数接口都需要一个无符号整型的参数代表串口号,串口号和串口是一一对应的,在DLL内部,串口号被转换为相应的MSComm串口控件。只要提供串口号就可以对相应的串口进行操作,这对于用户是十分方便的。比如,以下语句初始化并且打开一个串口(num为串口号):

2.2用户友好的消息机制设计

消息传递是Windows程序与程序之间以及程序内部进行交互的主要方式,该文采用自定义的消息来完成客户程序与DLL之间的交互。该文为DLL设计了三种消息,一旦MSComm控件有消息发出,将会被转换成这三种消息之一发送给客户程序。一种是接收数据消息:该消息通知客户程序,串口有数据到达;第二种是发送数据消息:该消息通知客户程序,串口上一批数据已经发送完,需要客户提供下一批待发送的数据;第三种是硬件控制消息或者是串口错误,比如串口clear-to-send线电平发生变化,奇偶校验错误等等。与直接使用MSComm控件相比,消息被清晰的分成三类,客户程序可以选择响应或者不响应哪类消息,而且第三类消息带有简要的文本,用户可以通过这个文本知道串口到底发生了什么问题,有利于用户调试程序。

消息的具体数值由客户程序来定义,在串口初始化的时候,将消息值传递给DLL。将来有相应的串口事件发生时,DLL就会将这些消息发送给客户程序。比如,下面的语句表明客户程序需要响应接收数据消息和硬件控制消息(或者串口错误消息),但不需要响应发送数据消息:

m_port2.init( GetSafeHwnd(), number, WM_COMMY_RCV, 0, WM_COMMY_OTHR );

其中,WM_COMMY_RCV表示接收数据消息,WM_COMMY_OTHR表示硬件控制消息和串口错误消息,这两个消息的数值都是客户程序自己定义的;m_port2是后文提到的C++串口类。

2.3用户友好的C++串口类设计

客户程序可以直接使用DLL的导出函数来进行串口编程,这些函数是C风格的函数。对于C++程序员,该文设计了一个C++串口类Mcomm,它是DLL导出函数的包装类(wrapper class)或者称为类(delegate class)[4]。客户程序通过Mcomm操作串口可以发挥充分发挥C++语言面向对象的优点,相对于C风格接口,它的接口更简单,它还能自动管理串口资源的获取和释放,减轻了客户程序的负担,使得串口编程更简洁方便,体现了简洁、清晰、易用的设计哲学。使用Mcomm时只需要像普通的C++类一样,将mcomm.h文件包含在项目中即可。

Mcomm类定义如下:

3 结束语

本文基于微软公司的ActiveX控件MSComm设计了一个串口通信DLL库,在此基础上设计了一个C++串口类,提供了一种对用户友好的串口编程途径,大大降低了串口编程的难度。程序员只需要最低限度的关于串口的知识,就可以用它来进行串口编程,这对非专业程序员和初学编程的人员非常有帮助。具有一定水平的程序员可以在此基础上实现更为复杂的串口操作,比如某种可靠的串口数据传输协议。该DLL库面向多种编程语言,使得非C/C++程序员也能够使用它来进行串口编程。该DLL库及C++串口类遵循源码开放的原则,有兴趣的读者可以与笔者联系取得本文的源代码。

参考文献:

[1] 李现勇.Visual C++串口通信技术与工程实践[M].北京:人民邮电出版社,2003.

[2] Kruglinski D J.Programming Visual C++.Microsoft Press,1998.

[3] 高传善.接口与通信[M].上海.复旦大学出版社,1992:10.

[4] 刘润东.UML对象设计与编程[M].北京:北京希望电子出版社,2001.

上一篇:基于xPC目标的串口数据实时通信 下一篇:网络信息工程的IP网络安全监测工作分析