当前位置:文档之家› com控件详解

com控件详解

com控件详解
com控件详解

MSComm控件提供了两种处理通信的方式:一种为事件驱动方式,该方式相当于一般程序设计中的中断方式。当串口发生事件或错误时,MSComm控件会产生OnComm事件,用户程序可以捕获该事件进行相应处理。本文的两个例子均采用该方式。另一种为查询方式,在用户程序中设计定时或不定时查询 MSComm控件的某些属性是否发生变化,从而确定相应处理。在程序空闲时间较多时可以采用该方式。

常用属性和方法

利用MSComm控件实现计算机通信的关键是理解并正确设置MSComm控件众多属性和方法。以下是MSComm控件的常用属性和方法:

●Commport:设置或返回串口号。

●Settings:以字符串的形式设置或返回串口通信参数。

●Portopen:设置或返回串口状态。

●InputMode:设置或返回接收数据的类型。

●Inputlen:设置或返回一次从接收缓冲区中读取字节数。

●InBufferSize:设置或返回接收缓冲区的大小,缺省值为1024字节。

●InBufferCount:设置或返回接收缓冲区中等待计算机接收的字符数。

●Input:从接收缓冲区中读取数据并清空该缓冲区,该属性设计时无效,运行时只读。

●OutBufferSize:设置或返回发送缓冲区的大小,缺省值为512字节。

●OutBufferCount:设置或返回发送缓冲区中等待计算机发送的字符数。

●Output:向发送缓冲区发送数据,该属性设计时无效,运行时只读。

●Rthreshold:该属性为一阀值。当接收缓冲区中字符数达到该值时,MSComm 控件设置Commevent属性为ComEvReceive,并产生OnComm事件。用户可在OnComm 事件处理程序中进行相应处理。若Rthreshold属性设置为0,则不产生OnComm 事件。例如用户希望接收缓冲区中达到一个字符就接收一个字符,可将Rthreshold设置为1。这样接收缓冲区中接收到一个字符,就产生一次OnComm 事件。

●Sthreshold:该属性亦为一阀值。当发送缓冲区中字符数小于该值时,MSComm 控件设置Commevent属性为ComEvSend,并产生 OnComm事件。若Sthreshold 属性设置为0,则不产生OnComm事件。要特别注意的是仅当发送缓冲区中字符数小于该值的瞬间才产生 OnComm事件,其后就不再产生OnComm事件。例如Sthreshold设置为3,仅当发送缓冲区中字符数从3降为2时,MSComm控件设置 Commevent属性为ComEvSend,同时产生OnComm事件,如发送缓冲区中字符始终为2,则不会再产生OnComm事件。这就避免了发送缓冲区中数据未发送完就反复发生OnComm事件。

●CommEvent:这是一个非常重要的属性。该属性设计时无效,运行时只读。一旦串口发生通信事件或产生错误,依据产生的事件和错误,MSComm控件为CommEvent属性赋不同的代码,同时产生OnComm事件。用户程序就可在OnComm 事件处理程序中针对不同的代码,进行相应的处理。 CommEvent属性的代码、常数及含义参见表1及表2。

表1 CommEvent通信事件代码常数含义

1 ComEvReceive 接受到Rthreshold个字符。该事件将持续产生,直到用Input 属性从接受缓冲区中读取并删除字符。

2 ComEvSend 发送缓冲区中数据少于Sthreshold个,说明串口已经发送了一些

数据,程序可以用Output属性继续发送数据。

3 ComEvCTS Clear To Send信号线状态发生变化。

4 ComEvDSR Data Set Ready信号线状态从1变到0。

5 ComEvCD Carrier Detect信号线状态发生变化。

6 ComEvRing 检测到振铃信号。

7 ComEvEOF 接受到文件结束符。

表2 CommEvent通信错误代码常数含义

1001 ComEvntBreak 接受到一个中断信号。

1002 ComEvntCTSTO Clear To Send信号超时。

1003 ComEvntDSRTO Data Set Ready信号超时。

1004 ComEvntFrame 帧错误。

1006 ComEvntOverrun 串口超速。

1007 ComEvntCDTO 载波检测超时。

1008 ComEvntRxOver 接受缓冲区溢出,缓冲区中已没有空间。

1009 ComEvntRxParity 奇偶校验错。

1010 ComEvntTxFull 发送缓冲区溢出,缓冲区中已没有空间。

1011 ComEvntDCB 检索串口的设备控制块时发生错误。

实例1:计算机拨号

在一些实际应用中经常需要使用计算机拨号。下面这个例子利用MSComm控件操作Modem进行拨号,实现串口通信。

实现步骤:

1.建窗体

●添加一个MSComm控件,用来建立与串口的连接;

●添加一个Text控件,Name属性为Txttel,用来输入电话号码;

●添加3个CommandButton控件,Name属性分别为DialButton、CancellButton、QuitButton,分别用来实现拨号、中止拨号、中止程序;

●添加一个Label控件,用来显示所有与拨号有关的信息。窗体见图1。

2.设置MSComm控件属性

●InBufferSize=1024;

●Inputlen=0;

●InputMode=0;

●Rthreshold=2;

●RTSEnable=True;

●Settings=“9600,N,8,1”;

●Sthreshold=0。

因为每一台计算机的串口使用状态都不会一样。为使程序具有通用性,在窗体的Load方法中首先进行串口测试,找到第一个可用串口后再进行设置。

CommPort属性设置并返回通讯端口号。

语法 https://www.doczj.com/doc/0e10303895.html,mPort[value ] (value 一整型值,说明端口号。)

说明在设计时,value 可以设置成从 1 到 16 的任何数(缺省值为 1)。但是如果用 PortOpen 属性打开一个并不存在的端口时,MSComm 控件会产生错误 68

(设备无效)。

注意:必须在打开端口之前设置 CommPort 属性。

RThreshold 属性:在 MSComm 控件设置 CommEvent 属性为 comEvReceive 并产生 OnComm 之前,设置并返回的要接收的字符数。

语法 object.Rthreshold [ = value ](value 整型表达式,说明在产生 OnComm 事件之前要接收的字符数。)

说明当接收字符后,若 Rthreshold 属性设置为 0(缺省值)则不产生 OnComm 事件。例如,设置 Rthreshold 为 1,接收缓冲区收到每一个字符都会使 MSComm 控件产生 OnComm 事件。

CTSHolding 属性:确定是否可通过查询 Clear To Send (CTS) 线的状态发送数据。Clear To Send 是调制解调器发送到相联计算机的信号,指示传输可以进行。该属性在设计时无效,在运行时为只读。

语法: object.CTSHolding(Boolean)

Mscomm 控件的 CTSHolding 属性设置值:

True Clear To Send 线为高电平。

False Clear To Send 线为低电平。

说明:如果 Clear To Send 线为低电平 (CTSHolding = False) 并且超时时,MSComm 控件设置 CommEvent 属性为 comEventCTSTO (Clear To Send Timeout) 并产生 OnComm 事件。

Clear To Send 线用于 RTS/CTS (Request To Send/Clear To Send) 硬件握手。如果需要确定 Clear To Send 线的状态,CTSHolding 属性给出一种手工查询的方法。

详细信息有关握手协议,请参阅 Handshaking 属性。

SThreshold 属性: MSComm 控件设置 CommEvent 属性为 comEvSend 并产生OnComm 事件之前,设置并返回传输缓冲区中允许的最小字符数。

语法 object.SThreshold [ = value ]

value 整形表达式,代表在 OnComm 事件产生之前在传输缓冲区中的最小字符数。

说明:若设置 Sthreshold 属性为 0(缺省值),数据传输事件不会产生 OnComm 事件。若设置 Sthreshold 属性为 1,当传输缓冲区完全空时,MSComm 控件产生 OnComm 事件。如果在传输缓冲区中的字符数小于 value,CommEvent 属性设置为 comEvSend,并产生 OnComm 事件。comEvSend 事件仅当字符数与Sthreshold 交叉时被激活一次。例如,如果 Sthreshold 等于 5,仅当在输出队列中字符数从 5 降到 4 时,comEvSend 才发生。如果在输出队列中从没有比Sthreshold 多的字符,comEvSend 事件将绝不会发生。

Handshake 常数

常数值描述

comNone 0 无握手。

comXonXoff 1 XOn/Xoff 握手。

comRTS 2 Request-to-send/clear-to-send 握手。

comRTSXOnXOff 3 Request-to-send 和 clear-to-send 握手皆可。

OnComm 常数

常数值描述

comEvSend 1 发送事件。

comEvReceive 2 接收事件。

comEvCTS 3 clear-to-send 线变化。

comEvDSR 4 data-set ready 线变化。

comEvCD 5 carrier detect 线变化。

comEvRing 6 振铃检测。

comEvEOF 7 文件结束。

Error 常数

常数值描述

comEventBreak 1001 接收到中断信号

comEventCTSTO 1002 Clear-to-send 超时

comEventDSRTO 1003 Data-set ready 超时

comEventFrame 1004 帧错误

comEventOverrun 1006 端口超速

comEventCDTO 1007 Carrier detect 超时

comEventRxOver 1008 接收缓冲区溢出

comEventRxParity 1009 Parity 错误

comEventTxFull 1010 传输缓冲区满

comEventDCB 1011 检索端口设备控制块 (DCB) 时的意外错误

InputMode 常数

常数值描述

comInputModeText 0 (缺省)通过 Input 属性以文本方式取回数据。comInputModeBinary 1 通过 Input 属性以二进制方式检取回数据。

CDHolding 属性:通过查询 Carrier Detect (CD) 线的状态确定当前是否有传输。Carrier Detect 是从调制解调器发送到相联计算机的一个信号,指示调制解调器正在联机。该属性在设计时无效,在运行时为只读。

语法 object.CDHolding

设置值:CDHolding 属性的设置值为:

设置描述

True Carrier Detect 线为高电平

False Carrier Detect 线为低电平

说明:注意当 Carrier Detect 线为高电平 (CDHolding = True) 且超时时,MSComm 控件设置CommEvent 属性为 comEventCDTO(Carrier Detect 超时错误),并产生 OnComm 事件。

注意在主机应用程序中捕获一个丢失的传输是特别重要的,例如一个公告板,因为呼叫者可以随时挂起(放弃传输)。

Carrier Detect 也被称为 Receive Line Signal Detect (RLSD)。

数据类型 Boolean

DSRHolding 属性:确定 Data Set Ready (DSR) 线的状态。Data Set Ready 信号由调制解调器发送到相连计算机,指示作好操作准备。该属性在设计时无效,在运行时为只读。

语法:object.DSRHolding

object 所在处表示对象表达式,其值是“应用于”列表中的对象。DSRHolding 属性返回以下值:

值描述

True Data Set Ready 线高

False Data Set Ready 线低

说明:当 Data Set Ready 线为高电平 (DSRHolding = True) 且超时时,MSComm 控件设置 CommEvent 属性为 comEventDSRTO(数据准备超时)并产生 OnComm 事件。

当为 Data Terminal Equipment (DTE) 机器写 Data Set Ready/Data Terminal Ready 握手例程时该属性是十分有用的。

数据类型:Boolean

Settings 属性: 设置并返回波特率、奇偶校验、数据位、停止位参数。

语法: object.Settings[ = value]

说明:当端口打开时,如果 value 非法,则 MSComm 控件产生错误 380(非法属性值)。

Value 由四个设置值组成,有如下的格式:

"BBBB,P,D,S"

BBBB 为波特率,P 为奇偶校验,D 为数据位数,S 为停止位数。value 的缺省值是:

"9600,N,8,1"

InputLen 属性:设置并返回 Input 属性从接收缓冲区读取的字符数。

语法 object.InputLen [ = value]

InputLen 属性语法包括下列部分:

value 整型表达式,说明 Input 属性从接收缓冲区中读取的字符数。

说明:InputLen 属性的缺省值是 0。设置 InputLen 为 0 时,使用 Input 将使 MSComm 控件读取接收缓冲区中全部的内容。

若接收缓冲区中 InputLen 字符无效,Input 属性返回一个零长度字符串 ("")。在使用 Input 前,用户可以选择检查 InBufferCount 属性来确定缓冲区中是否已有需要数目的字符。该属性在从输出格式为定长数据的机器读取数据时非常有用。

EOFEnable 属性:确定在输入过程中 MSComm 控件是否寻找文件结尾 (EOF) 字符。如果找到 EOF 字符,将停止输入并激活 OnComm 事件,此时 CommEvent 属性设置为 comEvEOF,

语法:object.EOFEnable [ = value ]

EOFEnable 属性语法包括下列部分:

value 布尔表达式,确定当找到 EOF 字符时,OnComm 事件是否被激活,如“设置值”中所描述。

value 的设置值:

True 当 EOF 字符找到时 OnComm 事件被激活。

False (缺省)当 EOF 字符找到时 OnComm 事件不被激活。

说明:当 EOFEnable 属性设置为 False,OnComm 控件将不在输入流中寻找 EOF 字符。

错误消息(MS Comm 控件)

下表列出 MSComm 控件可以捕获的错误:

值描述

380 无效属性值 comInvalidPropertyValue

383 属性为只读 comSetNotSupported

394 属性为只读 comGetNotSupported

8000 端口打开时操作不合法 comPortOpen

8001 超时值必须大于 0

8002 无效端口号 comPortInvalid

8003 属性只在运行时有效

8004 属性在运行时为只读

8005 端口已经打开 comPortAlreadyOpen

8006 设备标识符无效或不支持该标识符

8007 不支持设备的波特率

8008 指定的字节大小无效

8009 缺省参数错误

8010 硬件不可用(被其它设备锁定)

8011 函数不能分配队列

8012 设备没有打开 comNoOpen

8013 设备已经打开

8014 不能使用 comm 通知

8015 不能设置 comm 状态 comSetCommStateFailed

8016 不能设置 comm 事件屏蔽

8018 仅当端口打开时操作才有效 comPortNotOpen

8019 设备忙

8020 读 comm 设备错误 comReadError

8021 为该端口检索设备控制块时的内部错误 comDCBError

MSCom m1.Output = ”你的数据“ & Chr(13) '发出结束符

控件这个过程

Private Sub MSComm1_OnComm()

Dim ShuXing As String

ShuXing = Combo1(0) & "-" & Combo1(1) & "-" & Combo1(2) & "-" & Combo1(3) & "-" & Combo1(4)

Select Case https://www.doczj.com/doc/0e10303895.html,mEvent ' 借着取代底下每一个case 语句来处理每个事件与错误

Case comEvSend

COM_SJ Time, "发送事件", ShuXing, "发送事件"

Case comEvCD ' CD 线的状态发生变化.

COM_SJ Time, "发送状态", ShuXing, "发送数据已准备完毕"

Case comEvCTS ' CTS 线的状态发生变化.

COM_SJ Time, "清理数据", ShuXing, "清理发送区数据"

Case comEvDSR ' DSR 线的状态发生变化.

COM_SJ Time, "准备接收", ShuXing, "接收数据已准备完毕"

' Case comEvReceive ' 收到RThreshold 接收事件

' Form1.Caption = "监视窗口"

' Case comEvRing

' COM_SJ Time, "串口检测", ShuXing, "串口连接成功"

'

Case comEvEOF

COM_SJ Time, "文件结束", ShuXing, "收到文件结束字符"

Case comEventBreak

COM_SJ Time, "接收中断", ShuXing, "接收到一个中断信号"

Case comEventCTSTO

COM_SJ Time, "清理超时", ShuXing, "清理发送数据超时"

Case comEventDSRTO

COM_SJ Time, "准备超时", ShuXing, "准备数据超时"

Case comEventFrame

COM_SJ Time, "硬件错误", ShuXing, "硬件检测到一帧错误"

Case comEventOverrun

COM_SJ Time, "端口超速", ShuXing, "端口超速"

Case comEventCDTO

COM_SJ Time, "接收超时", ShuXing, "接收数据超时"

Case comEventRxOver

COM_SJ Time, "缓冲区溢出", ShuXing, "接受缓冲区溢出接收缓冲区没有空间"

Case comEventRxParity

COM_SJ Time, "奇偶校验错误", ShuXing, "硬件检测到奇偶校验错误"

Case comEventTxFull

COM_SJ Time, "缓冲区已满", ShuXing, "传输字符时传输缓冲区已满"

Case comEventDCB

COM_SJ Time, "端口意外错误", ShuXing, "检索端口的设备控制块(DCB) 时的意外错误"

End Select

If MSComm1.InBufferCount > 3 Then

RichTextBox1.UpTo RichTextBox1.Text, True, True '使光标回到文本的最后一行

RichTextBox1.SelText = MSComm1.Input '显示接受数据并在文本的最后一行显示

If HS >= 1000 Then '计算文件的长度SverTXT

RichTextBox1.Text = ""

End If

End If

End Sub

Option Explicit

Dim NowX As Integer '现在的X轴位置

Dim MaxPlotNo As Long '最长的X轴范围

Dim PreValue As Single '前一个测量值

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'当选择通信端口的Combo控件被选中后激活此事件

'若用户改变通信端口时,关闭通信端口

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Sub cmbCOM_Click()

'若通信端口号码和现在的选择一样时就不必理会,直接跳出此子程序

If cmbCOM.ListIndex + 1 = https://www.doczj.com/doc/0e10303895.html,mPort Then Exit Sub

Timer1.Enabled = False '关闭定时器

TimeDelay 100

If MSComm1.PortOpen Then

MSComm1.PortOpen = False '关闭通信端口

End If

lblMsg.Caption = "已停止检测并关闭通讯端口"

cmdOpenCOM.Enabled = True '允许使用【打开通信端口】按钮

End Sub

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'单击【结束】按钮后激活此事件

'使用End命令将系统结束

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Sub cmdEnd_Click()

End

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'单击【打开通信端口】按钮后激活此事件

'将MSComm控件的参数设置好,并打开

'激活【开始检测】按钮

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Sub cmdOpenCOM_Click()

'判断端口号码是否落在1--16之间

If cmbCOM.ListIndex >= 0 And cmbCOM.ListIndex <= 16 Then https://www.doczj.com/doc/0e10303895.html,mPort = cmbCOM.ListIndex + 1

Else

MsgBox "指定通信端口时发生错误!", vbCritical + vbOKOnly, "系统信息"

Exit Sub

End If

'激活错误检测机制

On Error GoTo comErr

MSComm1.Settings = "9600,n,8,1" '设定通信参数

MSComm1.PortOpen = True '打开通信端口

cmdOpenCOM.Enabled = False '将此按钮设为禁用状态

cmdStart.Enabled = True '激活【开始检测】按钮

lblMsg.Caption = "可单击【开始检测】按钮,执行检测的工作。"

Exit Sub

comErr:

MsgBox "打开通信端口时发生错误!请确定通信端口存在且正常。", vbCritical + vbOKOnly, "系统信息" End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'单击【开始检测】按钮后激活此事件

'将定时器激活或关闭,并显示对应的文字在按钮上,以指示用户操作

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Sub cmdStart_Click()

Timer1.Enabled = Not Timer1.Enabled

If Timer1.Enabled Then

cmdStart.Caption = "停止检测"

Else

cmdStart.Caption = "开始检测"

lblMsg.Caption = "已停止检测"

End If

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'窗体的Load事件

'输入图形暂时设为灰色,表示无状态信息进入

'将通讯端口号码及站号填入Combo控件;并默认二者的选项是第一个

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Sub Form_Load()

Dim i%

MaxPlotNo = 100

cmbCOM.Clear

cmbCOM.AddItem "COM1"

cmbCOM.AddItem "COM2"

cmbCOM.AddItem "COM3(USB)"

cmbCOM.AddItem "COM4(USB)"

cmbCOM.AddItem "COM5"

cmbCOM.AddItem "COM6"

cmbCOM.AddItem "COM7"

cmbCOM.AddItem "COM8"

cmbCOM.AddItem "COM9"

cmbCOM.AddItem "COM10"

cmbCOM.AddItem "COM11"

cmbCOM.AddItem "COM12"

cmbCOM.AddItem "COM12"

cmbCOM.AddItem "COM14"

cmbCOM.AddItem "COM15"

cmbCOM.AddItem "COM16"

cmbCOM.ListIndex = 0

cmdStart.Enabled = False

'以下设定绘图范围,(Xmin,YMax)-(XMax,YMin)

picTEMP.Scale (0, 1000)-(MaxPlotNo, 0)

picTEMP.DrawWidth = 2 '使用两个像素宽度的画笔

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'定时器的Timer事件引发后,就不断地执行其中的程序。

'将模拟读值命令送出,再取得返回字符串并判断。

'

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Sub Timer1_Timer()

Dim Buf$, ValueStr As Single, Pos1%

Buf$ = Buf$ + MSComm1.Input

TimeDelay 2150

ValueStr = Val(Mid(Buf, Pos1 + 1, 7)) '分离出正号以后的数值

lblValue.Caption = Format(ValueStr, "00.00") & "℃" '显示在画面上

If NowX = 0 Then

picTEMP.Cls '清除图形

picTEMP.PSet (0, ValueStr) '设定起点

Else

'以下判断现在的读值是否大于前一次的读值,若是,则以红色绘线

'若否,则以蓝色绘线

If ValueStr > PreValue + 0.01 Then

picTEMP.Line -(NowX, ValueStr), RGB(255, 0, 0) '由上一次的位置画至此点Else

picTEMP.Line -(NowX, ValueStr), RGB(0, 0, 255) '由上一次的位置画至此点End If

End If

PreValue = ValueStr

NowX = NowX + 1 '位置加1

If NowX > MaxPlotNo Then NowX = 0 '超过范围则数值归零

End Sub

Declare Function GetTickCount Lib "kernel32" () As Long

Sub TimeDelay(t As Long)

'时间延迟子程序,单位是毫秒(ms)

Dim TT&

TT = GetTickCount()

Do

DoEvents

Loop Until GetTickCount() - TT >= t

End Sub

'等待RS字符串返回,或是时间到达

'Comm是通信控件名称

'RS是欲等待的字符

'DT是最长的等待时间

'正常时返回值是所得的完整字符串,不正常时返回值是空字符串

Function WaitRS(Comm As MSComm, RS As String, DT As Long) As String

Dim Buf$, TT As Long

Buf = ""

TT = GetTickCount

Do

Buf = Buf & Comm.Input

Loop Until InStr(1, Buf, RS) > 0 Or GetTickCount - TT >= DT

If InStr(1, Buf, RS) > 0 Then

WaitRS = Buf

Else

WaitRS = ""

End If

End Function

vb6.0环境下,mscomm控件如何接收下位机发来的16进制数据?

因为mscomm的output只能接收string型的字符数据,而我的下位机发送出来的是16进制的数据,所以想问问这中间,怎么处理?

谢谢!

最佳答案

不用管下位机,要想收到字符型:

MSComm1.InputMode = comInputModeText

str = MSComm1.Input

要想收到十六进制:

MSComm1.InputMode = comInputModeBinary

ReDim InData(MSComm1.InBufferCount)

InData = MSComm1.Input

For i = 0 To UBound(InData)

If Len(Hex(InData(i))) = 1 Then

str = str & "0" & Hex(InData(i)) & " "

Else

str = str & Hex(InData(i)) & " " End If

相关主题
文本预览
相关文档 最新文档