OnComm 事件语法包括下列部分:
部分 描述
object 对象表达式,其值是“应用于”列表中的对象。
说明
CommEvent 属性包含实际错误或产生 OnComm 事件的数码。注意,设置 Rthreshold 或 Sthreshold 属性为 0,分别使捕获 comEvReceive 和 comEvSend 事件无效。
OnComm 事件示例
下例说明如何处理通讯错误和事件。可以在相关的 Case 语句之后插入代码来处理特定的错误或事件。
Private Sub MSComm_OnComm ()
Select Case MSComm1.CommEvent
' Handle each event or error by placing
' code below each case statement
' 错误
Case comEventBreak ' 收到 Break。
Case comEventCDTO ' CD (RLSD) 超时。
Case comEventCTSTO ' CTS Timeout。
Case comEventDSRTO ' DSR Timeout。
Case comEventFrame ' Framing Error
Case comEventOverrun '数据丢失。
Case comEventRxOver '接收缓冲区溢出。
Case comEventRxParity ' Parity 错误。
Case comEventTxFull '传输缓冲区已满。
Case comEventDCB '获取 DCB 时意外错误
' 事件
Case comEvCD ' CD 线状态变化。
Case comEvCTS ' CTS 线状态变化。
Case comEvDSR ' DSR 线状态变化。
Case comEvRing ' Ring Indicator 变化。
Case comEvReceive ' 收到 RThreshold # ofchars.
Case comEvSend ' 传输缓冲区有 Sthreshold 个字符 '
Case comEvEof ' 输入数据流中发现 EOF 字符
End Select
End Sub
CommEvent 属性
返回最近的通讯事件或错误。该属性在设计时无效,在运行时为只读。
语法
object.CommEvent
CommEvent 属性语法包括下列部分:
部分 描述
object 对象表达式,其值是“应用于”列表中的对象。
说明
只要有通讯错误或事件发生时都会产生 OnComm 事件,CommEvent 属性存有该错误或事件的数值代码。要确定引发 OnComm 事件的确切的错误或事件,请参阅 CommEvent 属性。
CommEvent 属性返回下列值之一来表示不同的通讯错误或事件。这些常数可以在该控件的对象库中找到。通讯错误包括下列设置值:
常数 值 描述
comEventBreak 1001 接收到一个中断信号。
comEventCTSTO 1002 Clear To Send 超时。在系统规定时间内传输一个字符时,Clear To Send 线为低电平。
comEventDSRTO 1003 Data Set Ready 超时。在系统规定时间内传输一个字符时,Data Set Ready 线为低电平。
comEventFrame 1004 帧错误。硬件检测到一帧错误。
comEventOverrun 1006 端口超速。没有在下一个字符到达之前从硬件读取字符,该字符丢失。
comEventCDTO 1007 载波检测超时。在系统规定时间内传输一个字符时,Carrier Detect 线为低电平。Carrier Detect 也称为 Receive Line Signal Detect (RLSD)。
comEventRxOver 1008 接受缓冲区溢出。接收缓冲区没有空间。
comEventRxParity 1009 奇偶校验。硬件检测到奇偶校验错误
comEventTxFull 1010 传输缓冲区已满。传输字符时传输缓冲区已满
comEventDCB 1011 检索端口的设备控制块 (DCB) 时的意外错误
通讯事件包括下列设置值:
常数 值 描述
comEvSend 1 在传输缓冲区中有比 Sthreshold 数少的字符。
comEvReceive 2 收到 Rthreshold 个字符。该事件将持续产生直到用 Input 属性从接收缓冲区中删除数据。
comEvCTS 3 Clear To Send 线的状态发生变化。
comEvDSR 4 Data Set Ready 线的状态发生变化。该事件只在 DST 从 1 变到 0 时才发生。
comEvCD 5 Carrier Detect 线的状态发生变化。
comEvRing 6 检测到振铃信号。一些 UART(通用异步接收— 传输)可能不支持该事件。
comEvEOF 7 收到文件结束(ASCII 字符为 26)字符。
数据类型
Integer
MSComm 控件示例
下面这个简单的例子演示了用调制解调器进行基本的串行通讯:
Private Sub Form_Load ()
' 保存输入子串的缓冲区
Dim Instring As String
' 使用 COM1。
MSComm1.CommPort = 1
' 9600 波特,无奇偶校验,8 位数据,一个停止位。
MSComm1.Settings = "9600,N,8,1"
' 当输入占用时,
' 告诉控件读入整个缓冲区。
MSComm1.InputLen = 0
' 打开端口。
MSComm1.PortOpen = True
' 将 attention 命令送到调制解调器。
' Chr$函数:返回 String,其中包含有与指定的字符代码相关的字符 。
MSComm1.Output = "ATV1Q0" & Chr$(13) ' 确保
' 调制解调器以"OK"响应。
' 等待数据返回到串行端口。
Do
DoEvents
Buffer$ = Buffer$ & MSComm1.Input
Loop Until InStr(Buffer$, "OK" & vbCRLF)
' 从串行端口读 "OK" 响应。
' 关闭串行端口。
MSComm1.PortOpen = False
End Sub
注意 MSComm 控件可以采用轮询或事件驱动的方法从端口获取数据。这个简单的例子使用了轮询方法。
实例1:计算机拨号
在一些实际应用中经常需要使用计算机拨号。下面这个例子利用MSComm控件操作Modem进行拨号,实现串口通信。
实现步骤:
1.建窗体
添加一个MSComm控件,用来建立与串口的连接;
添加一个Text控件,Name属性为Txttel,用来输入电话号码;
添加3个CommandButton控件,Name属性分别为DialButton、CancellButton、QuitButton,分别用来实现拨号、中止拨号、中止程序;
添加一个Label控件,用来显示所有与拨号有关的信息。窗体见图1。
2.设置MSComm控件属性
InBufferSize=1024; ’ InBufferSize 是指整个接收缓冲区的大小。缺省值是 1024 字节。
Inputlen=0; ’ InputLen 属性的缺省值是 0。设置 InputLen 为 0 时,使用 Input 将使 MSComm 控件读取接收缓冲区中全部的内容。
InputMode=0; ’0---(缺省)数据通过 Input 属性以文本形式取回。
1--数据通过 Input 属性以二进制形式取回
Rthreshold=2; ’ 当接收字符后,若 Rthreshold 属性设置为 0(缺省值)则不产生 OnComm 事件。
RTSEnable=True; ’ 当 RTSEnable 设置为 True,端口打开时,Request To Send 线设置为高电平,端口关闭时,设置为低电平。
Settings=“9600,N,8,1”;
Sthreshold=0。 ’ 若设置 Sthreshold 属性为 0(缺省值),数据传输事件不会产生 OnComm 事件。若设置 Sthreshold 属性为 1,当传输缓冲区完全空时,MSComm 控件产生 OnComm 事件。
因为每一台计算机的串口使用状态都不会一样。为使程序具有通用性,在窗体的Load方法中首先进行串口测试,找到第一个可用串口后再进行设置。
3.程序功能
程序根据输入的电话号码进行拨号,Modem正常拨号后,提示用户摘机,准备通话。
图1 电话拨号实例
4.主要方法与事件代码
'设置可用串口
Private Sub Form_Load()
On Error GoTo error_open
For i = 1 To 4
MSComm1.CommPort = 1
MSComm1.PortOpen = True
'设置可用的第一个串口
On Error GoTo 0
Exit Sub
error_resume:
Next
error_open:
Resume error_resume
End Sub
Private Sub DialButton_Click()
Dim Number$, Temp$
Number$ = Trim$(Txttel.Text) ’ 返回 Variant (String),其中包含指定字符串的拷贝,没有前导空白 (LTrim)、尾随空白 (RTrim) 或前导和尾随空白 (Trim)。
If Number$ = “" Then
MsgBox “请输入电话号码"
Txttel.SetFocus
Exit Sub
End If
DialButton.Enabled = False
QuitButton.Enabled = False
DialString$ =“ATDT”+ Number$ + “;” + vbCr | '清除接收缓冲区
MSComm1.InBufferCount =0
'拨电话号码
MSComm1.Output = DialString$
Lblmessage.Caption = “正在拨号码 -”+Number$
DialButton.Enabled = True
QuitButton.Enabled = True
End Sub
Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case comEvReceive
'读取串口数据
COMBUF=COMBUF + MSComm1.Input
lc = InStr(1, COMBUF, “OK”)
If lc = 0 Then Exit Sub
'Modem已正常拨号,返回OK
Lblmessage.Caption = “请您摘下电话机, 准备通话”
Case comEvSend
End Select
End Sub
Private Sub CancelButton_Click()
'断开与调制解调器的连接
MSComm1.Output = “ATH” + vbCr
End Sub
实例2:实现来电显示
在一些实际应用中,需要显示并保存来电号码,并根据电话号码显示相应资料,比如小区物业管理和110报警等系统。
实现步骤:
1.创建窗体
添加一个MSComm控件,用来建立与串口的连接;
添加4个Option控件,用来确定使用的串口号;
添加4个Label控件,用来显示来电号码及日期时间;
添加一个ProgressBar控件,用来显示电话振铃次数;
为方便调试程序,添加一个Text控件Text 5,用来显示Modem传来的所有信息。窗体见图2。
图2 来电显示窗体
2.设置MSComm控件属性
InBufferSize=1024;
Inputlen=0;
InputMode=0;
Rthreshold=1;
RTSEnable=True;
Settings=“9600,N,8,1";
Sthreshold=0。
3.程序功能
程序首先初始化Modem,然后等待来电。当有来电时,MSComm产生OnComm事件。Modem送出的信息格式为“DATE = 月日回车换行TIME = 时分回车换行NMBR = 电话号码回车换行”。在OnComm事件处理程序中对读入信息进行截取,截取电话号码后,以该电话号码为关键字,查询并显示数据库中有关信息。
4.主要方法与事件代码
'通用声明部分
Const DEBFLG = 1
Public COMX, BEEPNO, HANGUP,PNLOC As Integer
Public COMBUF, COMLIN As String
Private Sub Form_Load()
'检测串行口
Dim I, C As Integer
COMX = 0
COMBUF = “”
COMLIN = “”
BEEPNO = 0
HANGUP = 0
'正常运行程序,关闭右侧Text5
If DEBFLG= 0 Then
Form1.Width = Form1.Width - Text5.Width
Text5.Enabled = False
Text5.Visible = False
End If
On Error GoTo ERROR_FORM_LOAD
'检测可用串口
For C = 1 To 4
If MSComm1.PortOpen Then MSComm1.PortOpen = False
MSComm1.CommPort = C
If Not MSComm1.PortOpen Then
MSComm1.PortOpen = True
If MSComm1.PortOpen Then MSComm1.PortOpen = False
If COMX = 0 Then COMX = C
FORM_LOAD_1:
Next C
If COMX = 0 Then End
On Error GoTo 0
Option1(COMX - 1).Value = True
Exit Sub
ERROR_FORM_LOAD:
Option1(C - 1).Enabled = False
Resume FORM_LOAD_1
End Sub
'选择串行口
Private Sub Option1_Click(Index As Integer)
COMX = Index + 1
Call INIT_MODEM
End Sub
'初试化Modem
Private Sub INIT_MODEM()
If MSComm1.PortOpen Then MSComm1.PortOpen = False
MSComm1.CommPort = COMX
If Not MSComm1.PortOpen Then MSComm1.
PortOpen = True
MSComm1.Output = “AT#CID=1” + vbCr
'检查Modem命令是否完成
Call CHK_MODEM
MSComm1.Output = “ATS0=0” + vbCr
End Sub
'检查Modem命令是否完成
Private Sub CHK_MODEM()
Dim T As Single
Dim L As Integer
T = Timer
Do
COMBUF = COMBUF + MSComm1.Input
L = InStr(1, COMBUF,“OK”)
Loop Until L <> 0 Or Timer - T > 1
If L = 0 Then
Line1.Visible = True
Line2.Visible = True
Form1.Show
MsgBox “MODEM未联机”,vbOKOnly+vbCritical,“测试MODEM”
Else
Line1.Visible = False
Line2.Visible = False
End If
End Sub
'串行口接收事件处理
Private Sub MSComm1_OnComm()
Dim CH, ST As String
Dim LC As Integer
Select Case MSComm1.CommEvent
'接收到Rthreshold个字符
Case comEvReceive
COMBUF = COMBUF + MSComm1.Input
'读取串口数据
Do
LC = InStr(1, COMBUF, Chr(10))
If LC = 0 Then Exit Do
COMLIN = Left(COMBUF, LC)
COMBUF = Mid(COMBUF, LC + 1)
CH = Left(COMLIN, 1)
If “ ” < CH And CH < Chr(127) And DEBFLG = 1 Then
Text5.Text = Text5.Text + COMLIN
Text5.SelStart = Len(Text5.Text)
End If
'截取来电号码,并显示
If InStr(1, COMLIN“NMBR=”)<> 0 Then
ST = Mid(COMLIN, 8)
Text2.Text=“ ”+Left$(ST,Len (ST) -2) + “ ”
Form1.WindowState = 0
Timer1.Enabled = True
Call BEEP_NO
'截取来电日期,并显示
ElseIf InStr(1, COMLIN, “DATE = ”) <> 0 Then
Text3.Text = Str(Year(DATE)) + “.”+ Mid(COMLIN, 8, 2) + “.” + Mid(COMLIN, 10, 2) + “ ”
'截取来电时间,并显示
ElseIf InStr(1, COMLIN, “TIME = ”) <> 0 Then
Text4.Text = “ ” + Mid(COMLIN, 8, 2) + “:” + Mid(COMLIN, 10, 2)
'检测振铃个数
ElseIf InStr(1, COMLIN, “RING”) <> 0 Then
Call BEEP_NO
If HANGUP = 1 Or BEEPNO = 15 Then Call HANG_UP
'检测是否停止振铃
ElseIf Left(COMLIN, 3) = “000” Then
BEEPNO = 0
Timer1.Enabled = False
Form1.WindowState = 1
ProgressBar1.Value = 0
Frame3.Caption = “振铃数”
End If
Loop
'其他事件处理
Case comEvCTS
Case comEvDSR
Case comEvCD
Case comEvRing
Case comEventBreak
Call INIT_MODEM
Case Else
MsgBox “串口接收事件号:” & MSComm1.CommEvent & “ ”, vbOKOnly +
vbCritical, “测试串行口”
End Select
End Sub
MSComm控件是微软开发的专用通信控件,封装了串口的所有功能,使用很方便,但在实际应用中要小心对其属性进行配置。下面详 细说明该类应用方法。
3.1 MSComm控件的属性
CommPort:设置串口号,类型 short :1-comm1 2-comm2. Settings:设置串口通信参数,类型 CString :B波特率,P奇偶性(N无校验,E偶校验,O奇校验),D字节有效位数,S停止位。 PortOpen:设置或返回串口状态,类型 BOOL:TURE打开,FALSE关闭。 InputMode:设置从接收缓冲区读取数据的格式,类型 long: 0-Text 1-Bin。 Input:从接收缓冲区读取数据,类型 VARIANT。 InBufferCount:接收缓冲区中的字节数,类型:short。 InBufferSize:接收缓冲区的大小,类型:short。 Output:向发送缓冲区写入数据,类型:VARIANT。 OutBufferCount:发送缓冲区中的字节数,类型:short。 OutBufferSize:发送缓冲区的大小,类型:short。 InputLen:设置或返回Input读出的字节数,类型:short。 CommEvent:串口事件,类型:short。
3.2 程序示例
串口初始化
if (!m_comm.GetPortOpen())m_comm.SetPortOpen(TURE); /*打开串口*/
m_comm.SetSettings("4800,n,8,1"); /*串口参数设置*/ m_comm.SetInputMode(0); /*设置TEXT缓冲区输入方式*/ m_comm.SetRthresHold(1); /*每接收一个字符则激发OnComm()事件*/
接收数据
m_comm.SetInputLen(1); /*每次读取一个字符 VARINAT V1=m_comm.GetInput();
/*读入字符*/
m_V1=V1.bstrval;
发送字符 m_comm.SetOutput(Colevariant ("Hello"); /*发送 “Hello” */
注意:
SetOutput方法可以传输文本数据或二进制数据。用SetOutput方法传输文本数据,必须定义一个包含一个字符串的Variant。 发送二进制数据,必须传递一个包含字节数组的Variant 到 Output 属性。正常情况下,如果发送一个 ANSI 字符串到应用程序, 可以以文本数据的形式发送。如果发送包含嵌入控制字符、Null 字符等的数据,要以二进制形式发送。此处望引起读者注意,笔 者曾经在此犯错。 |
文章评论(0条评论)
登录后参与讨论