VB实现串口通讯.docx
- 文档编号:27307675
- 上传时间:2023-06-29
- 格式:DOCX
- 页数:11
- 大小:20.39KB
VB实现串口通讯.docx
《VB实现串口通讯.docx》由会员分享,可在线阅读,更多相关《VB实现串口通讯.docx(11页珍藏版)》请在冰豆网上搜索。
VB实现串口通讯
VB实现串口通讯
目前,VisualBasic(简称VB)已成为WINDOWS系统开发的主要语言,以其高效、简单易学及功能强大的特点越来越为广大程序设计人员及用户所青睐。
VB支持面向对象的程序设计,具有结构化的事件驱动编程模式并可以使用无限扩增的控件。
在VB应用程序中可以方便地调用WINDOWSAPI函数,使得编程效率提高,应用功能增强。
利用VB提供的这些功能,我们可以有三种方法完成串口通信。
一种是用VB提供的具有强大功能的通信控件;另一种方法是调用WINDOWSAPI函数,使用WINDOWS提供的通信函数编写移植性强的应用程序;第三是利用文件的输入/输出完成,该方法简便易行,但有一定的局限性。
一、利用通信控件(MSCOMM)完成串口通信
VB提供了通信控件MSCOMM,文件名为MSCOMM.VBX。
该控件可设置串行通信的数据发送和接收,对串口状态及串行通信的信息格式和协议进行设置。
在通信过程中可以触发OnComm事件,在该事件过程进行数据检验处理及检错,还可以通过编程访问CommEvent属性来了解通信的情况,进行收发数据的处理。
每个通信控件对应一个串口,如果要访问多个通信口,则要设计多个通信控件。
1、通信控件的事件及基本属性
(1)事件
OnComm:
通信控件只提供了一个事件,该事件的触发可以对串口的通信事件及错误进行处理。
通过对CommEvent属性的判断可知当前的通信错误和事件,分别对每个CommEvent值进行编程就完成了对各个错误和事件的处理。
如:
CommEvent=MSCOMM—EV—SEND表示发送事件。
这些信息可从VB提供的常量文件CONSTANT.TXT中查出。
(2)属性
CommPort:
设置通信控件与哪个串口相连接,设置并返回通信口号。
Setting:
设置通信的信息格式,为字符型。
顺序为:
波特率、校验、数据位、停止位。
PortOpen:
布尔型、开关通信口。
InputLen:
从接收缓冲区读取字符个数。
Input,Output:
读取接收缓冲区或写入发送缓冲区字符。
以上五种属性对串口完成基本的设置和操作,下面的三种属性是描述如何利用VB提供的事件驱动机制来实现通
信。
CommEvent:
返回通信过程中产生的错误信息及事件,了解通信状况。
SThreshold:
设置并返回不触发OnComm事件时发送缓冲区被允许的最少字符数。
当缓冲区的字符少于设置的值时,则触发OnComm事件,并把CommEvent设为MSCOMMM—EV—SEND。
当SThreshold=0则禁止发送触发OnComm事件,当SThreshold=1则发送缓冲区为空时就触发OnComm事件。
利用这一属性,就可完成发送数据后的一系列操作。
如:
对刚发送的数据进行处理,当串口是和MODEM通信时,发送完数据后可进行拆除线路联接、挂机等操作。
RThreshold:
设置并返回不触发OnComm事件时接收缓冲区被允许的最多字符数。
当缓冲区的字符多于设置的值时,则触发OnComm事件,并把CommEvent设为MSCOMM—EV—RECEIVE,当RThreshold=0则禁止接收触发OnComm事件,当RThreshold=1则接收缓冲区有一个或更多字符时就触发OnComm事件。
利用这一属性,就可完成对串口接收数据的处理。
2、利用通信控件的实例
SubForm1—load()
form1.show
′设置COM1
comm1.commport=1
comm1.Setting="9600,o,8,1"′波特率:
9600奇校验,8位数据,1位停止位
comm1.Inputlen=0′读取接收缓冲区的所有字符
comm1.OutBufferSize=512′设置发送缓冲区为512字节
comm1.InBufferSize=512′设置接收缓冲区为512字节
comm1.SThreshold=0′禁止发送事件
comm1.RThreshold=1′每一个字符到接收缓冲区都触发接收事件
′设置COM2
comm2.commport=2
comm2.Setting="2400,e,8,1"′波特率:
2400偶验,8位数据,1位停止位
comm2.Inputlen=0′读取接收缓冲区的所有字符
comm2.OutBufferSize=512′设置发送缓冲区为512字节
comm2.InBufferSize=512′设置接收缓冲区为512字节
comm2.SThreshold=1′发送缓冲区空触发发送事件
comm2.RThreshold=0′禁止接收事件
′打开COM1,COM2
comm1.Portopen=True
comm2.Portopen=True
Timer1.interval=5000
EndSub
SubComm1—OnComm()
DimInbuffasstring
Dimiasinteger,nasinteger,tasinteger
SelectCaseComm1.CommEven
caseMSCOMM—EV—RECEIVE
Inbuff=Comm1.Input
n=len(Inbuff)
Fori=1ton
t=Asc(Mid(Inbuff,i,1))or&HFF
printf
Nexti
EndSelect
EndSub
SubComm2—OnComm()
SelectCaseComm2.CommEvent
CaseMSCOMM—EV—SEND
Printtime
EndSelect
EndSub
SubTimer1—Timer()
Comm2.output=Second(Now)
Endsub
二、通过调用API函数实现通信
以上说明了用VB提供的控件实现通信的方法,只要理解了VB控件的机制就很容易完成对串口的操作,但可移植
性差。
但VB可以很容易调用API函数实现通信。
1、VB对API的调用
VB使用动态链接库DLL(DynamicLinkLibraries)的能力,大大扩展了其功能。
WINDOWS本身提供了API函数包括三大动态链接库:
KERNEL库、GDI库、USER库,通过VB用户可以直接调用这些库中的函数。
调用之前,必须首先在VB中声明。
该声明可为模块级或窗体级,当作为模块级声明时,其作用域为所有FORM和MODULE,而作为窗体级声明时其作用域为该声明所在的FORM。
VB调用DLL的格式:
DeclareSub过程名Lib″库名″[Alias″别名″]([ByVal参数As类型])
DeclareFunction函数名Lib″库名″[Alias″别名″]([ByVal参数As类型])As类型
在声明中:
DECLARE表示声明DLL中的函数,当声明是不具有返回值的过程时用SUB关键字,而如果调用的函数具
有返回值,则必须用FUNCTION关键字将其声明为函数并在声明语句的最后用AS指明函数返回值的类型。
LIB关键字表示当前声明的过程或函数是库名所指定的库中函数而非VB本身的函数。
库名,就是对应动态链接库的名称,其中通信函数在USER库中。
ByVal关键字将原参数数据类型一一对应到VB类型中。
WINDOWS的HELP文件WINSDK.HLP中包含了完整的WINDOWSAPI函数信息,可用该文件查看联机函数、数据结
构及错误信息。
2、API提供的通信函数
为了方便说明,我们将有关通信的函数及相关的数据结构放在全局模块中,文件名为COMM.BAS(见API编程函数
实例)。
以下是这些函数的基本介绍:
(1)OpenComm(IpComNameAsString,wInQueueAsInte-ger,wOutQueueAsInteger)
IpComName:
设备名,以“COMn”的形式来说明,n为设备号;wInQueue、wOutQueue:
分别以字节为单位说明发送、接收缓冲区的大小。
该函数调用成功返回打开的设备号,否则返回一负数代表错误信息码。
(2)SetCommState(IpDCBAsDCB)
IpDCB:
是DCB结构存放设备所希望的通信设置(DCB结构如COMM.BAS中所示),其中DCB的ID成员必须标识该
设备。
如果函数调用成功返回0;否则,返回值小于0。
(3)ReadComm(nCidAsInteger,IpBufAsString,nSizeAsInteger)
WriteComm(nCidAsInteger,IpBufAsString,nSizeAsIn-teger)
这是用来对通信设备进行读写的函数,nCid:
说明要读写的通信设备号,IpBuf:
为读写缓冲区,nSize:
为要读写的字节数。
如果读写成功,返回读写的字节数,否则是小于0的值,并且其绝对值为读写的字节数。
(4)Closecomm(nCidAsInteger)
该函数关闭nCid所指定的通信设备,并且释放分配给设备的发送,接收缓冲存储器,调用成功返回0;否则,返回值小于0。
(5)BuildCommDCB(IpDefAsString,IpDCBAsDCB)
lpDef:
为一字符串指定设备控制信息,此字符串具有MS-DOS中MODE命令所使用的参数形式。
IpDCB:
为一DCB数据结构。
该函数将IpDef字符串转换成串行设备控制块(DCB)代码。
(6)GetCommError(nCidAsInteger,IpStatAsCOMSTAT)
该函数检取nCid指定的设备最近的错误值和当前状态,IpStat:
是COMSTAT结构,具体形式如COMM.BAS中所定义的。
返回值为COMM.BAS中带CE-的常量的某种组合。
3.用API函数编程实例
这个例子是一仿真发送机,将从键盘输入的字符发送给COM端口。
在FORM中加一按钮COMMAND1来关闭通信口。
TypeDCB
IdAsString31
BaudRateAsInteger
ByteSizeAsString31
ParityAsString31
StopBitsAsString31
RlsTimeoutAsInteger
CtsTimeoutAsInteger
DsrTimeoutAsInteger
Bits1AsString31
Bits2AsString31
XonCharAsString31
XoffCharAsString31
XonLimAsInteger
XoffLimAsInteger
PeCharAsString31
EofCharAsString31
EvtCharAsString31
TxDelayAsInteger
EndType
TypeCOMSTAT
BitsAsString31
cbInQueAsInteger
cbOutQueAsInteger
EndType
DeclareFunctionOpenCommLib″User″(ByValIpComNameAs
String,ByValwInQueueAsInteger,ByValwOutQueueAsInteger)AsInteger
DeclareFunctionSetCommStateLib″User″(IpDCBAsDCB)
AsInteger
DeclareFunctionReadCommLib″User″(ByValnCidAsInteger,ByValIpBufAsString,ByValnSizeAsInteger)AsInteger
DeclareFunctionWriteCommLib″User″(ByValnCidAsInteger,ByValIpBufAsString,ByValnSizeAsInteger)AsInteger
DeclareFunctionClosecommLib″User″(ByValnCidAsInteger)AsInteger
DeclareFunctionBuildCommDCBLib″User″(ByValIpDefAs
String,IpDCBAsDCB)AsInteger
DeclareFunctionGetCommErrorLib″User″(ByValnCidAs
Integer,IpStatAsCOMSTAT)AsInteger
GlobalIpDCBAsDCB
GlobalnCidAsInteger
SubForm1—load()
DimcomsetAsString
comset=“COM2"
nCid=OpenComm(comset,512,512)′打开COM2设置接收,发送缓冲区为512字节
IfnCid<0Then′处理错误
MsgBox“不能打开COM:
"+Str(nCid)+“ErrorNum2
ber:
"+Str(nCid),16
end
endif
Command1.Caption=“关闭通信口"′设置串口DCB设备控制块
comset=“COM2:
9600,n,8,1"
If(BuildCommDCB(comset,LpDCB))Then
MsgBox“不能建立COMMDCB",16
end
endif
LpDCB.Id=Chr(nCid)
If(SetCommState(LpDCB))Then′设置串口状态
MsgBox"不能设置串口状态",16
end
endif
EndSub
SubForm1-keyPress(keyAsciiAsInteger)
DimnsendAsinteger,xAsinteger
DimLpstateAsCOMSTAT′通信状态块
Staticinbuffasstring
inbuff=imbuff+Chr(KeyAscii)
x=GetCommError(ncid,Lpstate)′读取当前串口错误或状态
iflpstate.cbOutQue<512Then′送缓冲区有空间否?
Nsend=WriteComm(nCid,inbuff,Len(inbuff))′发送inbuff
ifNsend<=0thenNsend=-Nsend′忽略错误
inbuff=Mid(inbuff,Nsend+1)′清除已发送的字符
endif
endif
EndSub
SubCommand1-Click()
DimNcloseAsinteger
Nclose=CloseComm(nCid)
IfNclose<0Then
MsgBox“不能关闭COMM口:
"+Str(nCid),16
end
else
ncid=0
endif
Cmmand1.Caption=“通信已关闭”
EndSub
三、用文件输入/输出技术完成通信
用VB提供的以上两种方法已足以应付各种串行通信的问题。
另外还可以用文件输入/输出的方法完成简单的通信应用程序,如拨号。
它用我们非常熟悉的BASIC输入/输出指令,如:
OPEN、CLOSE、GET、PUT(PRINT、WRITE)、ERR来完成打开、关闭、读、写和检错通信口的功能。
由于以上指令常在BASIC中使用,所以不在本文中详细介绍。
仅举一小例子来说一个为拨号操作,一个为挂机操作,程序很简单。
SubForm1—load()
DimTelnumAsSting
Command1.Caption=""
Command2.Caption=""
EndSub
SubCommand1—Click()
Open“COM2"ForOutputAs#1
print#1,Telnum
EndSub
SubCommand2—Click()
Telnum=“ATH"
Print#1,Telnum
Close#1
EndSub
这个小例子仅用了PRINT来发送数据,该命令自动在字符串后加了回车符。
其他指令如PUT、WRITE亦可完成。
但是注意变量TELNUM的格式,要在最后命令字符串后加回车符。
WINDOWS使用DOS操作完成文件处理,所以将通信端口当成文件来操作,就仅使用了DOS系统。
这种方法十分简便。
但是,使用文件输入/输出就使得通信不可靠,进来的字符可能遗漏,尤其是在2400b/s以上的速率传输数据时。
原因是这种方法仍基于DOS操作,使通信无法高速传输或在WINDOWS这样的多任务环境下使用。
经过长期的实践,笔者认为以上三种通信方法各有利弊。
如果在以低速传输且不十分复杂的情况下,那么可选用第三种方法。
而当在系统复杂传输速率高的情况下,则要选择前两种。
第一种学习起来快,而且程序为事件驱动程序模块化;使用第二种方法要对WINDOWSAPI函数有深入了解,对熟悉WINDOWSAPI函数的程序设计人员来说,无疑是个好方法,而且程序可移植性强
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VB 实现 串口 通讯
![提示](https://static.bdocx.com/images/bang_tan.gif)