分享

如何用VB编写串口程序

 xiaofenglib 2014-04-02
 

VB控件MSComm功能介绍

VB中的MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi等语言中均可使用。 Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。具体的来说,它提供了两种处理通信问题的方法:一是事件驱动(Event-driven)方法,一是查询法。

  1.MSComm控件两种处理通讯的方式

  MSComm控件提供下列两种处理通讯的方式:事件驱动方式和查询方式。

  1.1 事件驱动方式

  事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,在事件发生时需要得到通知,例如,在串口接收缓冲区中有字符,或者 Carrier Detect (CD) 或 Request To Send (RTS) 线上一个字符到达或一个变化发生时。在这些情况下,可以利用 MSComm 控件的 OnComm 事件捕获并处理这些通讯事件。OnComm 事件还可以检查和处理通讯错误。所有通讯事件和通讯错误的列表,参阅 CommEvent 属性。在编程过程中,就可以在OnComm事件处理函数中加入自己的处理代码。这种方法的优点是程序响应及时,可靠性高。每个MSComm 控件对应着一个串行端口。如果应用程序需要访问多个串行端口,必须使用多个 MSComm 控件。

  1.2 查询方式

  查询方式实质上还是事件驱动,但在有些情况下,这种方式显得更为便捷。在程序的每个关键功能之后,可以通过检查 CommEvent 属性的值来查询事件和错误。如果应用程序较小,并且是自保持的,这种方法可能是更可取的。例如,如果写一个简单的电话拨号程序,则没有必要对每接收一个字符都产生事件,因为唯一等待接收的字符是调制解调器的“确定”响应。

  2.MSComm 控件的常用属性

  MSComm 控件有很多重要的属性,但首先必须熟悉几个属性。

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

Settings  以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。 

PortOpen  设置并返回通讯端口的状态。也可以打开和关闭端口。

Input  从接收缓冲区返回和删除字符。 

Output  向传输缓冲区写一个字符串。

  下面分别描述:

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

  语法 object.CommPort[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 线高    当 Data Set Ready 线为高电平 (DSRHolding = True) 且超时时,MSComm 控件设置 CommEvent 属性为 comEventDSRTO(数据准备超时)并产生 OnComm 事件。

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

  数据类型:Boolean

False Data Set Ready 线低 

  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 字符。

3.错误消息(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 

 

 

   VB串口通讯MSCOMM控件 

标签:串口通讯 mscomm

 在Visual   Basic中有一个名为Microsoft   Communication   Control(简称MSComm)的通讯控件。 

  MSComm控件的主要属性、事件   

  

  1、MSComm的属性   

  

          由于MSComm控件属性很多,在此笔者仅介绍与实现串口通讯密切相关的核心属性。   

  

          Commport:设置通讯所占用的串口号。如设成1(默认值),表示对Com1进行操作。   

  

          Setting:对串口通讯的相关参数。包括串口通讯的比特率,奇偶校验,数据位长度、停止位等。其默认值   是“9600,N,8,1”,表示串口比特率是9600bit/s,不作奇偶校验,8位数据位,1个停止位。   

  

          Portopen:设置串口状态,值为True时打开串口,值为False时关闭串口。   

  

          Input:从输入寄存器读取数据,返回值为从串口读取的数据内容,同时输入寄存器将被清空。   

  

          Ouput:发送数据到输出寄存器。   

  

          InBufferCount:设置输入寄存器所存储的字符数,当将其值设为0时,则输入寄存器将被清空。   

  

        InputMode:设置从输入寄存器中读取数据的形式。若值为0,则表示以文本形式读取;值为1,则表示以   二进制形式读取。   

  

          OutBufferCount:设置输出寄存器所存储的字符数,当将其值设为0时,则输出寄存器将被清空。   

  

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

  

          CommEvent属性:返回最近的通讯事件或错误。通过对它具体属性值的查询,我们就可以获得通讯事件和通   讯错误的完整信息。当其值是comEvReceive时表示接收到数据。   

  

  2、MSComm的事件   

  

          除了公共事件之外,MSComm只有一个OnComm事件。当CommEvent属性值变化时将发生OnComm事件,指示发生   一个通讯事件或错误。当我们设置Rtheshold属性值为0时,将使得捕获comEvReceive事件无效。   

  

  三、串口通讯编程实例   

  

          在完成了对MSComm控件的简要介绍之后,笔者就以实际程序为例,介绍一下串口通讯的具体实现方法。 

  

  1、PC机间的串口通讯   

  

      (1)、实现方法:   

  

        A、新建一个窗体,在上面放两个Text控件、两个CommandButton控件和两个Label控件(如图1.bmp所示)。   

  

  具体见下表: 

  

  控件类型                       名称                         Caption属性                     作用   

  

  -------------------------------------------------------------------------------   

  

  Text                                 Text1                         -------                     输入所要发送的信息   

  

  Text                                 Text2                         -------                     显示接收到的信息   

  

  CommandButton               Command1                   发     送                           ---------                         

  

  CommandButton               Command2                   退     出                           ---------   

  

  Label                               Label1                   发送的数据                           提示   

  

  Label                               Label2                   接收的数据                           提示   

  

        B、在控件工具箱中的空白处点击鼠标右键,在弹出的菜单中选择“部件”,在弹出的窗口中的控件列表中   找到“Microsoft   Comm   Control”,将其选中,在点击“应用”、“关闭”,在控件工具栏中就会出现一个电   话的小图标。   

  

        C、用串口线将两台电脑连接起来。您可以使用Com1对Com1的对应连接,也可以使用Com1和Com2的交叉连接。   

  

  本程序使用的是Com1对Com1的连接。   

  

        D、输入以下代码:   

  

  Private   Sub   Command1_Click()   

  

  '...发送数据   

  

  MSComm1.OutBufferCount   =   0   '...清空输出寄存器   

  

  MSComm1.Output   =   Text1.Text   '...发送数据   

  

  End   Sub   

  

  Private   Sub   Command2_Click()   

  

  '...退出   

  

  Unload   Me   

  

  End   Sub   

  

  Private   Sub   Form_Load()   

  

  '...初始化   

  

  MSComm1.CommPort   =   1   '...使用Com1口   

  

  MSComm1.Settings   =   "9600,n,8,1"   '...设置通讯参数   

  

  MSComm1.PortOpen   =   True   '...打开串口   

  

  End   Sub   

  

  Private   Sub   Mscomm1_Oncomm()   

  

  '...通讯事件发生   

  

  Select   Case   MSComm1.CommEvent   

  

  Case   comEvReceive   '...有接受事件发生   

  

  Text2.Text   =   MSComm1.Input   '...接受显示数据   

  

  MSComm1.InBufferCount   =   0   '...清空输入寄存器   

  

  End   Select   

  

  End   Sub   

  

  2、PC机与单片机之间的通讯   

  

        PC机与单片机之间的通讯被广泛的用于工业、医疗测控等领域之中。在应用中,我们通常将单片机作为“感   受器”和“效应器”,负责数据采集、响应计算机发出的指令对电路进行控制,有时也进行一些简单的运算,   最后再将执行数据反馈给计算机处理。本程序将实现在PC机上输入一个0-255之间的整数,将此数据发送到单片   机,单片机接收到数据后,将数据在显示管上显示,再将此数除以2,将得数返回给PC机。(运行效果如图   3.BMP所示)其实现方法如下:   

  

          A、同PC机间通讯的实现方法A-B。   

  

          B、连接电脑和单片机。注意!由于PC机端的RS232电平与单片机端TTL的并不不匹配,故应注意电平转换。   

  

          C、在VB中输入以下代码:   

  

  Private   Sub   Mscomm1_Oncomm()   

  

  '...通讯事件发生   

  

  Dim   indata   As   Variant   

  

  Dim   bte(0)   As   Byte   

  

  Select   Case   MSComm1.CommEvent   

  

  Case   comEvReceive   '...有接受事件发生   

  

  indata   =   MSComm1.Input   

  

  '...注意!要通过MSComm控件发送或接收二进制数据必须用Variant类型的变量对二进   

  

  '...制Byte类型的变量进行转换!   

  

  bte(0)   =   AscB(indata)   

  

  Text2.Text   =   bte(0)   

  

  MSComm1.InBufferCount   =   0   '...清空输入寄存器   

  

  End   Select   

  

  End   Sub   

  

  Private   Sub   Command1_Click()   

  

  '...发送数据   

  

  Dim   Num   As   Integer   

  

  Dim   outbte(0)   As   Byte   

  

  Num   =   Val(Text1.Text)   

  

  outbte(0)   =   CByte(Num)   

  

  MSComm1.OutBufferCount   =   0   '...清空输出寄存器   

  

  MSComm1.Output   =   outbte(0)   '...发送数据   

  

  End   Sub   

  

  Private   Sub   Command2_Click()   

  

  '...退出   

  

  Unload   Me   

  

  End   Sub   

  

  Private   Sub   Form_Load()   

  

  '...初始化   

  

  MSComm1.CommPort   =   1   '...使用Com1口   

  

  MSComm1.Settings   =   "9600,n,8,1"   '...设置通讯参数   

  

  MSComm1.PortOpen   =   True   '...打开串口   

  

  End   Sub   

  

          D、单片机工作方式置于1,比特率设为9600bit/s。在单片机上,我们只得使用汇编语言编写,并且调用中   断实现对串口数据的收发工作。源代码如下:   

  

  PUSH   PSW                 ;将程序状态字压入堆栈   

  

  PUSH   ACC                 ;将累加器压入堆栈   

  

  CLR   EA                     ;关闭系统中断                     

  

  CLR   RI                     ;清除中断标志位   

  

  MOV   A,SBUF             ;从接收寄存器中读取数据   

  

  MOV   70H,A               ;分解数据百、十、个位并显示   

  

  MOV   B,#100             

  

  DIV   AB   

  

  MOV   52H,A               ;分解百位,送入存储器52H   

  

  MOV   A,B   

  

  MOV   B,#10   

  

  DIV   AB   

  

  MOV   51H,A               ;分解十位,送入存储器51H   

  

  MOV   50H,B               ;分解个位,送入存储器50H   

  

  MOV   A,70H   

  

  MOV   B,#2       

  

  DIV   AB                     ;将接受的数据除以2   

  

  MOV   SBUF,A             ;将得数发送到输出寄存器   

  

  ACALL   DL1               ;延时保证数据完整发送   

  

  ACALL   DL1   

  

  CLR   RI                     ;清除中断标志位   

  

  SETB   EA                   ;打开系统中断   

  

  POP   ACC                   ;累加器出栈   

  

  POP   PSW                   ;程序状态字出栈   

  

  RETI                         ;中断程序返回   

  

  3、编程环境   

  

            以上程序在Windows   2000   Professional,Visual   Basic   6.0企业版,AT89C52型单片机下调试通过。

VB中串口通讯的实现

 

一、概述

    串口通讯作为一种古老而又灵活的通讯方式,被广泛地应用于PC间的通讯以及PC和单片机之间的通讯之中。 提到串口通讯的编程,人们往往立刻想到C、汇编等对系统底层操作支持较好的编程语言以及大串繁琐的代码。

  实际上,只要我们借助相关ActiveX控件的帮助,即使是在底层操作一向不被人看好的VB中,一样能够实现串口通 讯,甚至其实现方法和C、汇编相比,要更加快捷方便。下面,笔者就介绍一下在VB中实现串口通讯的方法。

    在Visual Basic中有一个名为Microsoft Communication Control(简称MSComm)的通讯控件。我们只要通 过对此控件的属性和事件进行相应编程操作,就可以轻松地实现串口通讯。下面,笔者就简要地介绍一下

MSComm控件的使用方法。

二、MSComm控件的主要属性、事件

1、MSComm的属性

    由于MSComm控件属性很多,在此笔者仅介绍与实现串口通讯密切相关的核心属性。

    Commport:设置通讯所占用的串口号。如设成1(默认值),表示对Com1进行操作。

    Setting:对串口通讯的相关参数。包括串口通讯的比特率,奇偶校验,数据位长度、停止位等。其默认值 是“9600,N,8,1”,表示串口比特率是9600bit/s,不作奇偶校验,8位数据位,1个停止位。

    Portopen:设置串口状态,值为True时打开串口,值为False时关闭串口。

    Input:从输入寄存器读取数据,返回值为从串口读取的数据内容,同时输入寄存器将被清空。

    Ouput:发送数据到输出寄存器。

    InBufferCount:设置输入寄存器所存储的字符数,当将其值设为0时,则输入寄存器将被清空。

   InputMode:设置从输入寄存器中读取数据的形式。若值为0,则表示以文本形式读取;值为1,则表示以 二进制形式读取。

    OutBufferCount:设置输出寄存器所存储的字符数,当将其值设为0时,则输出寄存器将被清空。

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

    CommEvent属性:返回最近的通讯事件或错误。通过对它具体属性值的查询,我们就可以获得通讯事件和通 讯错误的完整信息。当其值是comEvReceive时表示接收到数据。

2、MSComm的事件

    除了公共事件之外,MSComm只有一个OnComm事件。当CommEvent属性值变化时将发生OnComm事件,指示发生 一个通讯事件或错误。当我们设置Rtheshold属性值为0时,将使得捕获comEvReceive事件无效。

三、串口通讯编程实例

    在完成了对MSComm控件的简要介绍之后,笔者就以实际程序为例,介绍一下串口通讯的具体实现方法。

1、PC机间的串口通讯

  (1)、实现方法:

   A、新建一个窗体,在上面放两个Text控件、两个CommandButton控件和两个Label控件(如图1.bmp所示)。

具体见下表:

控件类型           名称            Caption属性          作用

-------------------------------------------------------------------------------

Text                Text1            -------          输入所要发送的信息

Text                Text2            -------          显示接收到的信息

CommandButton       Command1         发  送             ---------           

CommandButton       Command2         退  出             ---------

Label               Label1         发送的数据             提示

Label               Label2         接收的数据             提示

   B、在控件工具箱中的空白处点击鼠标右键,在弹出的菜单中选择“部件”,在弹出的窗口中的控件列表中 找到“Microsoft Comm Control”,将其选中,在点击“应用”、“关闭”,在控件工具栏中就会出现一个电 话的小图标。

   C、用串口线将两台电脑连接起来。您可以使用Com1对Com1的对应连接,也可以使用Com1和Com2的交叉连接。

本程序使用的是Com1对Com1的连接。

   D、输入以下代码:

Private Sub Command1_Click()

'...发送数据

MSComm1.OutBufferCount = 0 '...清空输出寄存器

MSComm1.Output = Text1.Text '...发送数据

End Sub

Private Sub Command2_Click()

'...退出

Unload Me

End Sub

Private Sub Form_Load()

'...初始化

MSComm1.CommPort = 1 '...使用Com1口

MSComm1.Settings = "9600,n,8,1" '...设置通讯参数

MSComm1.PortOpen = True '...打开串口

End Sub

Private Sub Mscomm1_Oncomm()

'...通讯事件发生

Select Case MSComm1.CommEvent

Case comEvReceive '...有接受事件发生

Text2.Text = MSComm1.Input '...接受显示数据

MSComm1.InBufferCount = 0 '...清空输入寄存器

End Select

End Sub

2、PC机与单片机之间的通讯

   PC机与单片机之间的通讯被广泛的用于工业、医疗测控等领域之中。在应用中,我们通常将单片机作为“感 受器”和“效应器”,负责数据采集、响应计算机发出的指令对电路进行控制,有时也进行一些简单的运算, 最后再将执行数据反馈给计算机处理。本程序将实现在PC机上输入一个0-255之间的整数,将此数据发送到单片 机,单片机接收到数据后,将数据在显示管上显示,再将此数除以2,将得数返回给PC机。(运行效果如图 3.BMP所示)其实现方法如下:

    A、同PC机间通讯的实现方法A-B。

    B、连接电脑和单片机。注意!由于PC机端的RS232电平与单片机端TTL的并不不匹配,故应注意电平转换。

    C、在VB中输入以下代码:

Private Sub Mscomm1_Oncomm()

'...通讯事件发生

Dim indata As Variant

Dim bte(0) As Byte

Select Case MSComm1.CommEvent

Case comEvReceive '...有接受事件发生

indata = MSComm1.Input

'...注意!要通过MSComm控件发送或接收二进制数据必须用Variant类型的变量对二进

'...制Byte类型的变量进行转换!

bte(0) = AscB(indata)

Text2.Text = bte(0)

MSComm1.InBufferCount = 0 '...清空输入寄存器

End Select

End Sub

Private Sub Command1_Click()

'...发送数据

Dim Num As Integer

Dim outbte(0) As Byte

Num = Val(Text1.Text)

outbte(0) = CByte(Num)

MSComm1.OutBufferCount = 0 '...清空输出寄存器

MSComm1.Output = outbte(0) '...发送数据

End Sub

Private Sub Command2_Click()

'...退出

Unload Me

End Sub

Private Sub Form_Load()

'...初始化

MSComm1.CommPort = 1 '...使用Com1口

MSComm1.Settings = "9600,n,8,1" '...设置通讯参数

MSComm1.PortOpen = True '...打开串口

End Sub

    D、单片机工作方式置于1,比特率设为9600bit/s。在单片机上,我们只得使用汇编语言编写,并且调用中 断实现对串口数据的收发工作。源代码如下:

PUSH PSW        ;将程序状态字压入堆栈

PUSH ACC        ;将累加器压入堆栈

CLR EA          ;关闭系统中断         

CLR RI          ;清除中断标志位

MOV A,SBUF      ;从接收寄存器中读取数据

MOV 70H,A       ;分解数据百、十、个位并显示

MOV B,#100     

DIV AB

MOV 52H,A       ;分解百位,送入存储器52H

MOV A,B

MOV B,#10

DIV AB

MOV 51H,A       ;分解十位,送入存储器51H

MOV 50H,B       ;分解个位,送入存储器50H

MOV A,70H

MOV B,#2  

DIV AB          ;将接受的数据除以2

MOV SBUF,A      ;将得数发送到输出寄存器

ACALL DL1       ;延时保证数据完整发送

ACALL DL1

CLR RI          ;清除中断标志位

SETB EA         ;打开系统中断

POP ACC         ;累加器出栈

POP PSW         ;程序状态字出栈

RETI            ;中断程序返回

3、编程环境

     以上程序在Windows 2000 Professional,Visual Basic 6.0企业版,AT89C52型单片机下调试通过。

四、总结

    从以上程序可以看出,在VB中利用MSComm控件,可以快速开发出串口通讯程序,从而大大提高编程效率。

 

Visual Basic串口通讯调试方法

现有电子秤一台,使用串口与计算机进行通讯。编写VB程序来访问串口,达到读取电子秤上显示的数据。该电子秤为BE01型仪表,输出为RS-232C标准接口,波特率为300-9600、偶校验、7个数据位、2个停止位。所有字符均发送11位ASCII码,一个起始位。在VB中与串口通讯需要引入控件MSComm串口通讯控件(在Microsoft Comm Control 6.0中)。具体程序如下:控件简称:MSC

Dim Out(12) As Byte '接收var中的值
Dim var As Variant '接收MSC.input中的数值
Dim nRece As Integer '计算MSC.inputbuffer的个数
Dim i As Integer, j As Integer '随即变量,计算循环

****************************************************************************

Private Sub Form_Load()
 ClearText
 With MSC
  .CommPort = 1 '设置Com1为通信端口
  .Settings = "9600,E,7,2" '设置通信端口参数 9600赫兹、偶校验、7个数据位、1个停止位.(这里需要进一步说明的是:.Setting=”BBBB,P,D,S”。
  含义是:B:Baud Rate(波特率);P:Parity(奇偶);D:Data Bit;S:Stop Bit)

  .InBufferSize = 40 '设置缓冲区接收数据为40字节
  .InputLen = 1 '设置Input一次从接收缓冲读取字节数为1
  .RThreshold = 1 '设置接收一个字节就产生OnComm事件

 End With

End Sub

****************************************************************************

Private Sub ClearText()
 Text3.Text = ""
 Text2.Text = "5"
 Text1.Text = ""
End Sub

Private Sub Command1_Click()
 ClearText
 ' nRece = 0 '计数器清零
 With MSC
  .InputMode = comInputModeBinary '设置数据接收模式为二进制形式
  .InBufferCount = 0 '清除接收缓冲区
  If Not .PortOpen Then
   .PortOpen = True '打开通信端口
  End If
 End With
End Sub

Private Sub MSC_OnComm()
 DelayTime ‘用来延续时间
 ClearText
 With MSC
  Select Case .CommEvent '判断通信事件
  Case comEvReceive: '收到Rthreshold个字节产生的接收事件
   SwichVar 1
   If Out(1) = 2 Then '判断是否为数据的开始标志
    .RThreshold = 0 '关闭OnComm事件接收
   End If
   Do
    DoEvents
   Loop Until .InBufferCount >= 3 '循环等待接收缓冲区>=3个字节
   ' nRece = nRece + 1
   For i = 2 To 12
    SwichVar i
    Text1.Text = Text1.Text & Chr(Out(i))
   Next
   Text1.Text = LTrim(Text1.Text)
   Text2.Text = Text2.Text & CStr(nRece)
   .RThreshold = 1 '打开MSComm事件接收
  Case Else
   ' .PortOpen = False
  End Select
 End With

End Sub

****************************************************************************

Private Sub DelayTime()

 Dim bDT As Boolean
 Dim sPrevious As Single, sLast As Single

 bDT = True

 sPrevious = Timer (Timer可以计算从子夜到现在所经过的秒数,在Microsoft Windows中,Timer函数可以返回一秒的小数部分)

 Do While bDT
  If Timer - sPrevious >= 0.3 Then bDT = False
 Loop
 bDT = True

End Sub

(通信传输速率为9600bps,则最快速度1.04ms发送一个字节,仪表每秒发送50帧数据,每帧数据有4个字节,即每秒发送200个字节,平均5.0ms 发送一个字节,连续读取串口数据时要在程序中添加循环等待程序)

Private Sub SwichVar(ByVal nNum As Integer)

 DelayTime
 var = Null
 var = MSC.Input
 Out(nNum) = var(0)

End Sub

(设置接收数据模式采用二进制形式,即 InputMode=comInputModeBinary,但用Input属性读取数据时,不能直接赋值给 Byte 类型变量,只能通过先赋值给一个 Variant 类型变量,返回一个二进制数据的数组,再转换保存到Byte类型数变量中。)

Private Sub Text1_Change()

 Text3.Text = CText(Text1.Text) - CText(Text2.Text)

End Sub

****************************************************************************

Private Function CText(ByVal str As String) As Currency

 If str <> "" Then
  CText = CCur(Val(str))
 Else
  CText = 0
 End If

End Function

  (仪表每秒发送50帧数据,微机收到一帧完整数据至少需要20 ms时间,然后再进行数据处理。如果微机在下一帧数据接收前即20ms内能将数据计算处理完毕,则接收缓冲区内只会保存有一帧数据,不会存有两帧以上数据,接收缓冲区的大小不会影响实时监测效果(接收缓冲区>4字节),这时完全可以实现实时监测或实时控制;如果微机在20ms内不能将数据计算处理完毕,接收缓冲区设置得又很大,在数据计算处理完毕前,接收缓冲区内就会保存有两帧以上数据,而且一次工作时间越长,缓冲区内滞留数据帧就越多,数据采集和数据处理之间产生逐渐增大的额外时间差,当接收缓冲区充满后,时间差不再增大,固定在某一值,部分数据因不能及时采集到接收缓冲区中,数据产生丢失现象,真实工作情况就会和微机处理结果产生较大的时间差,对实时监测和实时控制很不利,这种情况下接收缓冲区的大小就会影响实时监测效果,所以接收缓冲区设置不能过大,以保证数据处理的实时性。) 小结:本文所用的仪表为梅特勒公司出产的BE01型电子秤,其输出的每个编码均为标准的ASCII码。其他的仪表存在发射的编码中含有BCD压缩码,而且分为高低位,需要接收后对其进行解码换算,之后还要将高位和低位数字进行相加,即可以将其BCD码换算成实数。另还存在误差的可能:判断最大值,仪表在刚开始工作时有干扰,会传导一些乱码,位移传感器有参数偏差,最大值一般都略大于50毫米,所以取51为极限最大值,取-51为极限最小值。暂时先写这些,当然其他的情况可以依此类推!

VB串口通讯实例

高精度电压表(24bit)  VB源程序
Dim PortValue As Integer    端口号选择1-4
Dim value As Double         当前一次取值
Dim value2 As Double        要显示的值
Dim valueSum As Double        和
Dim numCount As Double      算平均值是的计数个数
Dim func As Integer         功能号标志1-4
Dim valueFlag As Integer
Private Sub Check1_Click()
自动刷新 被选中则 刷新按钮无效
If Check1.value Then
    Command1.Enabled = False
Else
    Command1.Enabled = True
   
    Command1.SetFocus
End If
End Sub
Private Sub Command1_Click()
    显示
    Call display
End Sub
Private Sub Command2_Click()
    valueSum = 0 清计数和
    numCount = 1 清计数个数
    Label6.Caption = Str(numCount - 1) 显示复位
    value = 0
    value2 = 0
    valueFlag = 0
    Call display
End Sub
Private Sub Form_Activate()
    numCount = 1
    value = 0
    valueSum = 0
    PortValue = 1
    Text1.Visible = False
    Label6.Caption = "0"
    Option1(0).value = True
    Option2(0).value = True
    Command1.SetFocus
    Label1.Caption = Format(value2, "0.000,000")
    For i = 0 To 3
        If Option2(i).value = True Then
            func = i + 1
        End If
    Next i
    Check1.value = 1
    Call ComPortOpen
End Sub
Public Sub ComPortOpen() 开串口
    With MSComm1
        .CommPort = PortValue              使用COM1
        .Settings = "9600,N,8,1"       设置通信口参数
        .InBufferSize = 40
        设置MSComm1接收缓冲区为40字节
        .OutBufferSize = 2
        设置MSComm1发送缓冲区为2字节
        .InputMode = comInputModeBinary
        设置接收数据模式为二进制形式
        .InputLen = 1
        设置Input 一次从接收缓冲读取字节数为1
        .SThreshold = 1
        设置Output 一次从发送缓冲读取字节数为1
        .InBufferCount = 0  清除接收缓冲区
        .OutBufferCount = 0     清除发送缓冲区
        MaxW = -99
        最大值赋初值
        MinW = 99             最小值赋初值
        w = 0
        数据个数计数器清零
        .RThreshold = 1
        On Error Resume Next
        设置接收一个字节产生OnComm事件
        If .PortOpen = False Then
            判断通信口是否打开
            .PortOpen = True       打开通信口
            If Err Then        错误处理
                msg = MsgBox(" 串口 COM" & PortValue & " 无效! ", vbOKOnly, "警告")
                Exit Sub
            End If
        End If
    End With
    MsgBox "端口已打开"
End Sub
Public Sub ComPortClose() 关串口
    MSComm1.PortOpen = False
       MsgBox "端口已关闭"
End Sub
Private Sub MSComm1_OnComm()
    Call recive
End Sub
Private Sub Option1_Click(Index As Integer)
    If MSComm1.PortOpen = True Then
        Call ComPortClose
    End If
    PortValue = Index + 1
    Call ComPortOpen
End Sub
Private Sub recive() 检测起始位并接收数据
    Dim Buffer As Variant
    Dim Arr() As Byte
    Dim inData(5) As Byte
    Dim count  As Integer
    Dim temp As Byte
   
   
      MsgBox "OnComm"
    With MSComm1
   
            Select Case .CommEvent
            判断MSComm1通信事件
                Case comEvReceive
                    收到Rthreshold个字节产生的接收事件
                    Buffer = .Input
                    Arr = Buffer
                   
                    读取一个接收字节
                    Text1.Text = Arr(0)
                    If Arr(0) = &H1B Then
                        .RThreshold = 0
                        Do
                            DoEvents
                        Loop Until .InBufferCount >= 4
                       
                        For i = 1 To 4
                            count = .InBufferCount
                            Buffer = .Input
                            Arr = Buffer
                            inData(i) = Arr(0)
                        Next i
                        If inData(4) = &HA Then
                            If (inData(1) Mod 64) >= 32 Then
                                .RThreshold = 1
                                Exit Sub
                            End If
                            valueFlag = 1
                            0.000003814697265625
                            temp = inData(1) Mod 16
                            If temp <= 7 Then
                                value = inData(1) Mod 8
                                value = value * 256 * 256
                                value = value + Val(inData(2)) * 256
                                value = value + Val(inData(3))
                                value = value * 3.814697265625E-06
                                Text1.Text = Format(value, "0.000,000")
                            Else
                                value = inData(1) Mod 8
                                value = value * 256 * 256
                                value = value + Val(inData(2)) * 256
                                value = value + Val(inData(3))
                                value = value * 3.814697265625E-06
                                value = 0 - value
                            End If
                            temp = inData(1) Mod 128
                            test OF
                            If temp >= 64 Then
                                If value < 0 Then
                                    value = value - 0.000004
                                Else
                                    value = value + 0.000004
                                End If
                            End If
                            检测自动刷新
                            If Check1.value Then
                                 valueFlag = 1
                                 Call display
                            End If
                        Else
                            .RThreshold = 1
                            Exit Sub
                        End If
                        .InBufferCount = 0
                        .RThreshold = 1
                    End If
            Case Else
        End Select
    End With
    Text1.Text = Text1.Text + 1
End Sub
Private Sub Option2_Click(Index As Integer)
    func = Index + 1
End Sub
Public Sub display() 判断功能并显示
   
    功能选择
    Select Case func
        Case 1 当前值
            value2 = value
           
        Case 2 平均值
            If numCount > 100000 Then
                numCount = 1
                valueSum = 0
            End If
            If valueFlag = 1 Then
                valueSum = valueSum + value
                value2 = valueSum / numCount
                numCount = numCount + 1
                valueFlag = 0
                Label6.Caption = Str(numCount - 1)
            End If
        Case 3 最大值
            If value > value2 Then
                value2 = value
            End If
        Case 4 最小值
            If value < value2 Then
                value2 = value
            End If
        Case Else
    End Select
    Text1.Text = Str(valueSum)
    Label1.Caption = Format(value2, "0.000,000")
   
End Sub
Private Sub Timer1_Timer()清缓冲区
    Text1.Text = MSComm1.InBufferCount
    If MSComm1.InBufferCount >= 80 Then
        MSComm1.InBufferCount = 0
    End If
End Sub

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多