[转] VB Mscomm控件应用
| Visual Basic 6.0(以下简称VB) 是一种功能强大、简单易学的程序设计语言。它不但保留了原先Basic语言的全部功能,而且还增加了面向对象程序设计功能。它不仅可以方便快捷地编制适用于数据处理、多媒体等方面的程序,而且利用ActiveX控件MSComm还能十分方便地开发出使用计算机串口的计算机通信程序。本文结合计算机通信的两个例子,详细介绍如何在VB中使用MSComm控件。 |
| 处理方式 |
| 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通信事件
|
表2 CommEvent通信错误
|
| 实例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方法中首先进行串口测试,找到第一个可用串口后再进行设置。 |
| 3.程序功能 |
| 程序根据输入的电话号码进行拨号,Modem正常拨号后,提示用户摘机,准备通话。 |
|
| 4.主要方法与事件代码 |
| '设置可用串口 |
| Private Sub Form_Load() |
| On Error GoTo error_open |
| For i = 1 To 4 |
| MSComm1.CommPort = i |
| 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) |
| 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.设置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 |



浙公网安备 33010602011771号