一、 概述 众所周知,微软公司的VisualBasic、Visual C++ 是快速、简便地开发Windows应用程序的有力工具,它为开发具有良好、标准的图形用户界面的应用程序提供了全面的支持,深受广大编程者的欢迎。在许多应用里,涉及到在Windows环境下进行计算机与计算机、计算机与智能设备之间交换字节数据而非文本数据的通信问题,解决这类问题的一种较好途径是利用VB/VC提供的串行通信控件MSComm。 下面介绍的两种实现字节通信方式的方法不仅适合于Visual Basic和Visual C++,而且也适合于其它编程环境,例如: Delphi,C++ Builder等。 二、用字符通信方式实现字节通信方式 对于5.0以前版本的VB/VC,所提供的通信控件只能用字符通信方式进行数据的发送和接收。若要用于字节数据的通信,发送方须在发送之前对待发数据用某种算法施以变换。接收方在接收后须用相应算法对数据进行逆变换。 对于要发送的一系列字节数据,可将其按每8个字节一组分成若字节干组,若最后一个字节组不足8个字节,则用0填充。发送时,按字节块逐个进行,每个字节块中包括一个字节组。字节块的具体结构为:第1个字节为本字节块的标识码;为了避免传送ASCII码以外的信息和ASCII码中的控制字符,第2-9个字节依次为要发送的字节组中的各个字节的低7位的值加32;第10个字节从高位位到低位依次为要发送的字节组中的各个字节的最高位。 至于接收方,在每接收到一个字节块后,就进行 如下解包处理:首先,根据字节块的标识码来判断所含 数据是第几个字节组,若是最后一组,实际有几个数据字节。然后根据字节块与字节组的关系从字节块的第2-10个字节中恢复出字节组,完成了8个字节数据的传输。 显然,用这种方法实现字节通信算法法较复杂,且由于要多安排一个字节依次存放字节组中各个字节的低7位与32的和,通信效率稍低。 三、直接实现字节通信方式 从VB5/VC5开始,微软的通信控件不仅支持字符通信方式,而且还增加了对字节通信方式的支持,即可直接发送和接收字节类型的数据,很好地满足了许多通信应用场合。 我们来看看Visual Basic 5.0和 Visual C++5.0的通信控件中几个与字节通信方式有密切关系的主要属性和事件: InputMode属性:InputMode表示检取数据的类型。其取值不仅可以为comInputModeText,还可取comInputModeBinary。前者表示检取的是文本数据,即字符数据;后者表示检取的是8位二进制数据,即字节数据。 Input属性:若InputMode设置为comInputModeText,则Input属性将返回Variant类型的文本数据。若InputMode设置为comInputModeBinary,则Input属性将返回一个Variant类型的二进制数据。 Settings属性:设置或返回波特率、奇偶校验、数据位和停止位参数。 OutBufferSize属性:设置或返回发送缓冲区的大小。 InBufferSize属性:设置或返回接收缓冲区的大小。 CommEvent属性:返回最近的通信事件或错误。 RThreshhpld属性:设置或返回在MSComm控件将CommEvent属性设置为comEvReceive并产生OnComm事件之前所接收的字符数。该属性用于中断方式。 PortOpen属性:设置或返回通信端口的状态(打开或关闭)。 Settings属性: 设置或返回通信端口的波特率、数据格式。 Input属性: 设置或返回接收缓冲区种的数据流。 Output属性: 将数据写入发送缓冲区。 OnComm事件:当CommEvent属性改变时产生该事件,表明产生了通信事件或通信错误。属性用于中断方式。 在直接实现字节通信方式时应注意如下两点:1. 将通信控件的属性InputMode设置 成comInputModeBinary。2. 定义一个Variant类型的变量和一个字节类型的数组,用于存放的待发数据或已收数据并在它们之间进行强制类型转换。 四、应用举例 下面介绍一个用VB5编写的直接实现字节通信方式的简单例子,其方法同样适合于Visual C++、Delphi和C++Builder 等。 假设我们已经将计算机的RS-232标准串行口COM1的2(接收)脚和3(发送)脚短接,即从COM1的TXD引脚发送出去的数据又由COM1的RXD引脚接收回来。MSComm1为VB5或VB6的通信控件;SendData为按钮控件,用于下达发送数据命令,Tx_Data为文本盒控件,用于显示刚发出的数据;Rx_Data为文本盒控件,用于显示刚收到的数据。 程序采用中断方式处理接收到的数据。每接收一个字节数据产生一次中断请求,在中断服务程序中将收到的数据显示于Rx_Data文本盒中。 Dim S As String Dim I As Byte Dim N As Integer Private Sub Form_Load() MSComm1.CommPort= 1 MSComm1.InputMode=comInputModeBinary MSComm1.OutBufferSize= 512 MSComm1.InBufferSize= 512 MSComm1.RThreshold =1 MSComm1.Settings ="1200,n,8,1" MSComm1.PortOpen =True End Sub Private Sub Form_Unload(Cancel As Integer) MSComm1.PortOpen =False End Sub Private Sub SendData_Click() Dim Buffer AsVariant Dim Arr(0) As Byte Arr(0) = I Buffer = Arr MSComm1.Output =Buffer Tx_Data.Text =Str(Arr(0)) I = I + 1 End Sub Private Sub MSComm1_OnComm() Select CaseMSComm1.CommEvent 'ERRORS CasecomEventBreak CasecomEventCDTO CasecomEventCTSTO CasecomEventDSRTO CasecomEventFrame CasecomEventOverrun CasecomEventRxOver CasecomEventRxParity CasecomEventTxFull CasecomEventDCB 'EVENTS CasecomEvCD CasecomEvCTS CasecomEvDSR CasecomEvRing CasecomEvReceive: Receive_handler CasecomEvSend CasecomEvEOF End Select End Sub Private Sub Receive_handler() Dim Buffer AsVariant Dim Arr() As Byte Buffer =MSComm1.Input Arr = Buffer Rx_Data.Text =Str(Arr(0)) End Sub 本例介绍的方法成功地应用到我们开发的微机继电保护测试仪等产品的上位机与下位机的通信中。
|