串行接口是微机与外部设备的主要通信接口之一。只需要一条信号线就可以进行单向数据传送。由于线路简单,价格相对较低,得到了广泛应用。
图1 近距离时系统连接方式
如果想利用串行接口来实现近距离通信(通常15米以内),可以采用图1的连接方式来实现。该接收机采用EIA-RS232C串行标准进行通信,其数据通信信号形式如下表:
波特率(Baud) | 4800, 9600, or 19200 bps |
数据位(Databit) | 8 bits |
停止位(Stopbit) | 2 bits |
校验位(Parity) | Non |
流控制(Flow Control) | XON / XOFF |
接收机接收通过串口接收来自PC机的控制命令后,进行相应的动作,完成相应的设置。那么如何在WINDOWS环境下快速有效地开发串口通信程序呢?一般情况下的串口通信无非采用两种方法:一是利用Windows 的通信API 函数, 二是利用一些高级语言(如VC++等)来实现。Windows 的API 函数虽然使用面很广,但由于比较复杂而有一定的难度,而Visual C++ 的ActivateX 控件, 由于其灵活性与易用性而受广大计算机开发者的青睐,正成为主要的开发工具。
二、ActiveX控件介绍
ActiveX是Windows 下进行应用程序开发的崭新技术,它的核心内容是组件对象模型COM(Component Object Model)。ActiveX控件包括一系列的属性、方法和事件,使用ActiveX控件的应用程序和ActiveX控件之间的工作方式是客户/服务器方式,即应用程序通过ActiveX控件提供的接口来访问ActiveX控件的功能。
Microsoft Communication control是Microsoft公司提供的简化Windows下串行接口收发数据的简便方法。下面介绍在Visual C++6.0环境下,用ActiveX通信控件来编程实现串口通信的方法和技巧。
三、串口通信的编程实现
用VC++的Active X控件来实现串口通信,是一种快速简洁而又简单的编程方法。下面简单介绍实现过程。
3.1 在程序中嵌入通信控件
单击Project菜单中选择Add to Project,再单Components and Controls,从弹出的对话框中单击Registered ActiveX Controls,然后在列表框中选择Microsoft Communications Control, version 6.0,单击OK。之后注意到Project中新增加了一个类。通过查看类MSComm的源文件mscomm.cpp,我们可以了解这个控件的属性和使用方法,其中的Get...函数可以用来访问该属性的当前值,而Set...函数则用来设置该属性的新值。
3.2 利用串口通信类编程实现通信功能
在添加了串口通信类之后,就可以在相应的程序中创建一个通信控件,然后通过调用串口通信类的成员函数来完成相应的数据接收和发送功能。
四、 串口通信的使用方法和技巧
4.1 通过人工映射事件自动响应函数
通信控件的工作原理类似与中断方式,当有通信事件发生时(如发送数据、接收数据等),就会触发OnComm事件,在该事件的处理函数中调用OnCommEvent()函数,通过返回值即可确定是那类事件,再作出相应的处理。
但需要注意的是,OnCommEvent()函数并不是自动映射的,必须手工添加该事件映射函数。其方法如下:
示例中是在主框架类中调用通信控件类函数。所以先要在Mainfrm.h添加如下消息映射函数。
afx_msg void OnCommEvent();
然后在Mainfrm.cpp中添加如下代码
BEGIN_EVENTSINK_MAP(CMainFrame, CFrameWnd)
ON_EVENT(CMainFrame, ID_COMMCTRL, 1, OnCommEvent, VTS_NONE)
END_EVENTSINK_MAP()
接下来就可以在void CMainFrame::OnCommEvent()函数中处理各种串口响应事件。
串口收发数据时,若数据只用 ANSI 字符集,则用文本方式收发。对其它字符数据,如数据中有嵌入控制字符、Nulls 等等,则使用二进制方式。
其中一个需要注意的问题是函数SetInput()发送的是VARIANT型变量,而我们输入的一般是CString型变量,因此必须进行转换。先将CString型变量转换为BYTE型数组,再将转换为ColeSafeArray型变量,然后将其组转换为VARIANT型变量发送出去。这个转换过程看起来比较复杂,但它可以满足用不同的变量类型来发送数据。在串口接收数据时,也要做类似的变量类型转换处理。该转换的主要代码实现如下所示:
void CMainFrame::OnSendData(CString m_strInputData,int kind) { CString str,string; VARIANT strReceive; BYTE data[256]; long i,length; COleSafeArray m_input2; length=m_strInputData.GetLength(); //将Cstring型变量转换为BYTE型数组 for(i=0;i<length;i++) data[i]=m_strInputData.GetAt(i); length++; //创建一个ColeSafeArray型变量数组 m_input2.CreateOneDim(VT_UI1,length,data,0); //把字节数组转换成ColeSafeArray型变量 for(i=0;i<length;i++) m_input2.PutElement(&i,data+i); //把ColeSafeArray型变量转换成VARIANT型变量 strReceive=m_input2; //发送数据 m_commctrl.SetOutput(strReceive); } |
我们知道,每个使用的串口通信控件对应着一个串行端口。如果应用程序需要访问多个串行端口,必须使用多个控件。通常,PC机配有两个串行接口,分别以COM1和COM2标称。所以如果需要在同一应用程序中,对两个接收机进行遥控时,就可以通过创建两个串口通信控件来实现。并且PC机也可以根据需要添加新的串行接口硬件,所以通过多个串口通信控件就能很容易地实现与多个外部设备的通信。
五、 结束语
本文实现了在windows98下用Visual C++来开发某侦察接收机与PC机串行通信的接口程序,并且利用ActiveX控件大大简化了程序设计的难度。本文给出了部分关键实现的代码,并根据作者开发经验,指出了需要注意的问题,具有一定的实用意义。