1、四川工业学院学报J ournal of Sic h uan University of Science an d Tec h nology文章编号 : 100025722 (2003)增刊 20003203收到日期 :2003205201作者简介 :阚能琪 (19752) ,男 ,西华大学能源与环境工程系助教 ,大学本科 ,现为西南交通大学计算机与通信工程学院硕士研究生 ,主要研究方向 :通信与信息系统、水利水电动力工程。MSComm 控件在串口编程中的应用阚能琪 1 ,汪 鑫 2(11 西华大学能源与环境工程系 ,四川 成都 610039 ;21 西华大学机械工程与自动化系 ,四川 成都 6
2、10039)摘 要 : 文章介绍了在 Windows下进行串行通信编程 ,MSComm 控件提供的两种处理通信问题的方法 :事件驱动方式和查询方式 ,并对利用 MSComm控件进行串口编程的流程做了深入分析。关键词 : MSComm控件 ;串口 ;事件驱动方式 ;查询方式中图分类号 :TP311. 11 文献标识码 :B0 引言在很多情况下 ,远程监控和工业自动化领域系统常见的通信编程多为串并口编程 ,计算机串并口编程在通信软件中有着十分广泛的应用 ,如电话、传真、视频和控制等。随着面向对象编程技术的发展 ,在面向对象集成开发环境中 (如 Visual c 6 、 Delphi、 Visual
3、 Basic等 ) ,利用开发环境本身已有的控件进行开发设计 ,从而减少开发时间 ,节约开发投资 ,具有重要的现实意义。本文首先介绍了在 Windows 下进行串行通信编程 ,MSComm控件提供的两种处理通信问题的方法 ,再对其编程流程做了深入分析 ,使读者了解在面向对象集成开发环境下 ,利用已有控件进行串口通信编程的一般方法。1 MSComm 控件处理通信问题的两种基本方法MSComm是 Microsoft 公司提供的简化 Windows 下串行通信编程的 ActiveX控件 ,它为应用程序提供了通过串行接口收发数据的简便方法。具体来说 ,它提供了两种处理通信问题的方法 :一是事件驱动 (
4、 Event -driven)方法 ,一是查询法。111 事件驱动方式事件驱动通信是处理串行端口交互作用的一种非常有效的方法 。在许多情况下 ,在事件发生时需要得到通知 ,例如 ,在串口接收缓冲区中有字符 ,或者 Carri2er Detect (CD)或 Request To Send(RTS)线上一个字符到达或一个事件发生时。在这些情况下 , 可以利用MSComm控件的 OnComm事件捕获并处理这些通信事件。 OnComm时间还可以检查和处理通信错误。 Com2mEvent 属性列出了所有通信事件和通信错误 ,可以通过查阅 MSDN (Microsoft Developer Networ
5、k) 获得。在编程过程中 ,就可以在 OnComm 时间处理函数中加入自己的处理代码。这种方法的优点是程序响应及时 ,可靠性高。每个 MSComm 控件对应着一个串行端口。如果应用程序需要访问多个串行端口 ,必须使用多个MSComm 控件。112 查询方式查询方式实质上还是属于事件驱动 ,但在某些情况下 ,这种方式显得更为便捷。在程序的每个关键功能之后 ,可以通过检查 CommEvent 属性的值来查询事件和错误 ,只要 CommEvent 属性的值发生变化 ,就表明一个通信时间或一个错误发生。如果应用程序较小 ,并且是自成一体的 ,这种方法可能是更可取的。例如 ,如果写一个简单的电话拨号程序
6、 ,则没有必要对每接收一个字符都产生事件 ,因为唯一等待接收的字符是调制解调器的“确定”响应信息。在 PC 机串行端口通信时 ,使用了十几条线进行信号传输 , 这 5 条线的高低电平状态分别对应MSComm 空间相应属性的 True/ False 值。DTR 线 :用于传输 PC 机发往串口 Modem 等设备的信号 ,该信号表示 PC 机是非已经准备好。RTS线 :用于传输 PC 机发往串口 Modem 等设备的信号 ,该信号表示 PC 机是非允许 Modem发数据。DSR线 :用于传输串口 Modem 等设备发往 PC 机 1994-2007 China Academic Journal
7、Electronic Publishing House. All rights reserved. http:/的信号 ,该信号表示 Modem 等设备是非已经作好操作准备。CTS 线 :用于传输串口 Modem等设备发往 PC 机的信号 ,该信号表示 Modem是非允许发送数据。CD 线 :用于传输串口 Modem 等设备发往 PC 机的信号 ,该信号表示 Modem 已经和远方的设备建立了联系。MSComm 控件的通信功能的实现 ,实际上是调用了 API函数 ,而 API函数是由 Comm. drv 解释并传递给驱动程序进行的。2 MSComm 控件串口编程 2基本流程VC610 6 提供
8、的 MSComm 控件通过串行端口发送和接收数据 ,为应用程序提供串行通信功能 ,使用方便 ,下面对 VC610 6 中使用 MSComm 进行通信编程进行介绍。211 在当前 Project 中插入 MSComm控件打开“ Project Add To Project Components and Con2trols Registered ActiveX Controls 菜单选择 Compo2nents :Microsoft Communicationgs Control ,version 610 命令插入到当前的 Project 中。则添加了 CMSComm 类。类CMSComm的相关文
9、件 mscomm1h 和 mscomm1cpp 也一并加入 Project 中。如果 Project 中的视图类是基于 CFormView 类的 ,那么创建 CMSComm 是相当简单的。只需在 CFor2mView 对应的对话框窗体中插入 CMSComm 控件 ,再在视图类的 ClassWizard 中为该空间声明一个变量即可。如果视图类不是基于 CFormView 的 ,那么就需要建立一个 CMSComm控件。创建的方法和普通的 ActiveX控件的创建类似。下面是一个例子 :在 MainFrm1h 中添加下面声明语句 :protected : CMSComm m- Com ;在 Main
10、Frm1cpp : :On2Create ()函数中添加下列创建控件的语句 :DWORD style = WS- VISIBLE| WS- CHILD ;if ( ! m - Com1Create (NULL , style , Crect ( 0 , 0 , 0) ,this ,ID - COMMCTRL) )TRACE0 ( Failed to cteate OLE Communications Con2trol n” ) ;return - 1 ; fail to create212 初始化并打开串口对串口进行初始化一般来说要完成以下几个设置 :设定通信端口号 ,即 CommPort 属
11、性。设定通信协议 ,即 HandShaking 属性。设定传输速率等参数 ,即 Settings 属性。设定其他一些参数 ,视具体情况加上其它的属性设定。打开通信端口 ,即将 PortOpen 属性设为 TRUE。下面通过一段代码对上述步骤进行说明 (假定m - Com 是有效的 CMSComm对象 ) :m - Com1SetCommPort (1) ; 选择 COM1m - Com1SetInBufferSize (1024) ; 设置输入缓冲区的大小 ,Bytesm - Com1SetOutBufferSize (512) ; 设置输出缓冲区的大小 ,Bytesif ( ! m - Co
12、m1GetPortOpen() 打开串口m - Com1SetPortOpen(TRUE) ;m - Com1SetInputModel (1) ; 设置输入方式为二进制方式m - Com1SetSettings(” 9600 ,n ,8 ,1) ; 设置数据传输速率等参数m - Com1SetRThreshold(1) ; 为 1 表示有一个字符引发一个事件m - Com1SetInputLen(0) ;213 捕捉串口事项MSComm 控件可以采用查询或事件驱动的方法从端口获取数据。这里介绍使用比较广泛的事件驱动方法 :有事件 (如接收到数据 )发生时通知程序 ,并在程序中需要捕获并处理这
13、些通信事件。下面的例子简单地实现对串口事项的捕捉。在 MainFrm1h 中添加 :protected :afx - msg void OnCommMscomm() ;DECLARE- EVENTSINK- MAP在 MainFrm1cpp 中添加事件的映射 :BEGIN - EVENTSINK- MAP ( CmainFrame ,CframeWnd)ON - EVENT ( CmainFrame , ID - COMMCTRL , 1 , On2CommMscomm ,VTS- NONE) 映射 ActiveX控件事件END - EVENTSINK- MAP()214 串口读写串口的读写主
14、要利用两个函数 GetInut ( ) 和SetOutput 来实现。两个函数的原形是 :VARIANT Ger2Input ( ) 及 void SetOutput (const VARIANT都要是用 VARIANT 类型 (所有 Idispatch : : Invoke 的参数和返回值在内部都是作为 VARIANT 对象处理的 ) 。无论是在 PC 机读取上传数据时还是在 PC 机发送下行命令是 ,习惯于使用字符串的形式 (也可以说是数组形式 ) 。查阅 VARIANT文档知道 ,可以用 BSTR 表示字符串 ,但遗憾的是所有的 BSTR 都包含宽字符 ,即使我4 四川工业学院学报 20
15、03 年 1994-2007 China Academic Journal Electronic Publishing House. All rights reserved. http:/们没有定义 - UNICODE- 也是这样 ! Windows NT 支持宽字符 ,而 windows 95 并不支持。为解决上述问题 ,可以使用 CbyteArray ,下面给出相应的部分程序 :void CmainFrame : :OnCommMscomm()VARIANT vResponse ;int k ;if (m - Com1GetCommEvent () = = 2)k = m - Com1Ge
16、tInBufferCount () ; / 接收到的字符数目if (k 0)vResponse = m - Com1GetInput () ; read 对数据进行其他处理接收到字符 ,MSComm控件发送事件处理其他 MSComm 控件void CmainFrame : :OnCommSend()准备需要发送的命令 ,放在 TxData 中CbyteArray array ;array1RemoveAll () ;array1SetSize (Count) ;for (i = 0 ; i Count ; i + + ;) array1SetAt (i , TxDatai ) ;m - Com
17、1SetOutput (Cole Variant (array) ) ; 发送数据215 关闭串口在使用完 MSComm 通信对象后 ,需要将通信端口关闭。当然如果窗体注销时 ,MSComm 控件注销同样可以完成这一功能。可以用下面的语句来实现这个功能 :m - Com1SetPortOpen(FALSE) ;3 结束语利用 MSComm 控件在 Windows 环境下进行串口通信编程的技术 ,在工业控制和许多其他领域中都有着举足轻重的作用 ,对缩短软件开发的周期 ,减少软件开发的投资 ,都具有重要的意义。参 考 文 献1 李现勇 1Visual C 6 串口通信技术与工程实践 M1 北京 :
18、人民邮电出版社 ,200212 (美 ) David J1Kruglinski ,潘爱民 ,王国印译 1Visual C 6 技术内幕M1 北京 :清华大学出版社 ,199913 侯俊杰 1 深入浅出 MFCM1 武汉 :华中科技大学出版社 ,20011Application of MSComm Controler in Series2Port ProgrammingKAN Neng2qi1 ,WANG Xin2(11Dept1 of Power 21Dept1 of Mechanical Engineering and Automation of Xihua University , Che
19、ngdu 610039 Sichuan China)Abstract :This paper puts forward methods of series2port programming in windows system ,and presents two methods aboutdealing with communication problems : event2driven way and query way ,and procedure of series2port programming by usingMSComm controler1Key words :MSComm controler ;event2driven way ; query way5增刊 阚能琪 等 :MSComm控件在串口编程中的应用 1994-2007 China Academic Journal Electronic Publishing House. All rights reserved. http:/