labview串口通讯的深入分析.docx
《labview串口通讯的深入分析.docx》由会员分享,可在线阅读,更多相关《labview串口通讯的深入分析.docx(13页珍藏版)》请在冰豆网上搜索。
![labview串口通讯的深入分析.docx](https://file1.bdocx.com/fileroot1/2023-4/21/9ae53911-07ce-483f-a097-1bb73624a8cd/9ae53911-07ce-483f-a097-1bb73624a8cd1.gif)
labview串口通讯的深入分析
labview称做"G"语言,只是说明了它具备了通用编程语言的编程能力,但是任何编程语言都有器独特的特点,否则经过几十年的风风雨雨,并没有出现一种编程语言一统天下的格局,每种编程语言都有其特别适合的领域,从这点来说,数据采集和仪器通讯可以说是它最擅长的领域.毫无疑问,计算机的串口通讯是相对比较简单的通讯方式,labview也不例外地对它提供了支持.
LABVIEW的串口控制,可以通过多种方法:
1.最基本的INOUT控制,LABVIEW提供了Inport和OutPort两个基本输入输出VI,通过它就可以直接读写寄存器,我本人做的许多并口控制设备就是利用了这两个节点,在计算机的DOS时代,通过INOUT指令进行串口通讯是唯一的选择,现在正在做单片机的朋友都知道,单片机的串口通讯都是通过操作寄存器实现的,对于计算机的COM1,它的端口地址是0X3F8,完全可以通过它来完成串口通讯.
2.利用API的WriteFile函数实现串口通讯,这是VC进行串口通讯的方法.
3.利用VB提供的MSCOMM控件(这是目前用的最多的,它支持查询和中断两种模式,即可以发送文本型数据(ASCII),由可以发送二进制(BIN,实际是BYTEARRAY)
4.利用LABVIEW特有的VISA通讯
直接控制寄存器的方法在计算机串口通讯基本看不到了.只有在单片机中还采用这种方式.
通过C51串口通讯,简单地介绍一下这种方法:
/*发送数据函数 */
voidSendData(uchar*buf)
{
uchari;
ucharlen;
len=strlen(buf);/*取得字符串长度*/
for(i=0;i
{
SBUF=buf[i];/*SBUF是串口输出REG */
while(!
TI);/*等待发送完成 */
TI=0;/*复位中断标志 */
}
}
方法2直接调用API非常复杂,在LV不会采用,就不介绍了.
方法3是目前用的最多,介绍一下.
MSComm控件提供下列两种处理通讯的方式:
事件驱动方式和查询方式。
来源:
2.1事件驱动方式
事件驱动通讯是处理串行端互作用的一种非常有效的方法。
在许多情况下,在事件发生时需要得到通知,例如,在串口接收缓冲区中有字符,或者CarrierDetect(CD)或RequestToSend(RTS)线上一个字符到达或一个变化发生时。
在这些情况下,可以利用MSComm控件的OnComm事件捕获并处理这些通讯事件。
OnComm事件还可以检查和处理通讯错误。
所有通讯事件和通讯错误的列表,参阅CommEvent属性。
在编程过程中,就可以在OnComm事件处理函数中加入自己的处理代码。
这种方法的优点是程序响应及时,可靠性高。
每个MSComm控件对应着一个串行端口。
如果应用程序需要访问多个串行端口,必须使用多个MSComm控件。
2.2查询方式
查询方式实质上还是事件驱动,但在有些情况下,这种方式显得更为便捷。
在程序的每个关键功能之后,可以通过检查CommEvent属性的值来查询事件和错误。
如果应用程序较小,并且是自保持的,这种方法可能是更可取的。
例如,如果写一个简单的电话拨号程序,则没有必要对每接收一个字符都产生事件,因为唯一等待接收的字符是调制解调器的“确定”响应。
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属性:
确定是否可通过查询ClearToSend(CTS)线的状态发送数据。
ClearToSend是调制解调器发送到相联计算机的信号,指示传输可以进行。
该属性在设计时无效,在运行时为只读。
语法:
object.CTSHolding(Boolean)
Mscomm控件的CTSHolding属性设置值:
TrueClearToSend线为高电平。
FalseClearToSend线为低电平。
说明:
如果ClearToSend线为低电平(CTSHolding=False)并且超时时,MSComm控件设置CommEvent属性为comEventCTSTO(ClearToSendTimeout)并产生OnComm事件。
ClearToSend线用于RTS/CTS(RequestToSend/ClearToSend)硬件握手。
如果需要确定ClearToSend线的状态,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-setready线变化。
comEvCD
5
carrierdetect线变化。
comEvRing
6
振铃检测。
comEvEOF
7
文件结束。
Error常数
常数
值
描述
comEventBreak
1001
接收到中断信号
comEventCTSTO
1002
Clear-to-send超时
comEventDSRTO
1003
Data-setready超时
comEventFrame
1004
帧错误
comEventOverrun
1006
端口超速
comEventCDTO
1007
Carrierdetect超时
comEventRxOver
1008
接收缓冲区溢出
comEventRxParity
1009
Parity错误
comEventTxFull
1010
传输缓冲区满
comEventDCB
1011
检索端口设备控制块(DCB)时的意外错误
InputMode常数
常数
值
描述
comInputModeText
0(缺省)
通过Input属性以文本方式取回数据。
comInputModeBinary
1
通过Input属性以二进制方式检取回数据。
CDHolding属性:
通过查询CarrierDetect(CD)线的状态确定当前是否有传输。
CarrierDetect是从调制解调器发送到相联计算机的一个信号,指示调制解调器正在联机。
该属性在设计时无效,在运行时为只读。
语法object.CDHolding
设置值:
CDHolding属性的设置值为:
设置
描述
True
CarrierDetect线为高电平
False
CarrierDetect线为低电平
说明:
注意当CarrierDetect线为高电平(CDHolding=True)且超时时,MSComm控件设置CommEvent属性为comEventCDTO(CarrierDetect超时错误),并产生OnComm事件。
注意在主机应用程序中捕获一个丢失的传输是特别重要的,例如一个公告板,因为呼叫者可以随时挂起(放弃传输)。
CarrierDetect也被称为ReceiveLineSignalDetect(RLSD)。
数据类型:
Boolean
DSRHolding属性:
确定DataSetReady(DSR)线的状态。
DataSetReady信号由调制解调器发送到相连计算机,指示作好操作准备。
该属性在设计时无效,在运行时为只读。
语法:
object.DSRHolding
object所在处表示对象表达式,其值是“应用于”列表中的对象。
DSRHolding属性返回以下值:
值
描述
说明
True
DataSetReady线高
当DataSetReady线为高电平(DSRHolding=True)且超时时,MSComm控件设置CommEvent属性为comEventDSRTO(数据准备超时)并产生OnComm事件。
当为DataTerminalEquipment(DTE)机器写DataSetReady/DataTerminalReady握手例程时该属性是十分有用的。
数据类型:
Boolean
False
DataSetReady线低
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.错误消息(MSComm控件)
下表列出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
以上这部分转载于网上.
labview可以直接调用ACTIVEX控件,所以可以直接使用,新版本的LV可以注册回调函数(REG CALLBACK),所以这个控件的所有功能都是可用的,下面示意一下调用的方法.
重点介绍一下VISA串口通讯的方法:
基本流程是:
打开(配置)--->循环(读写)--->关闭(释放)
一共有八个VI节点
1.VISAConfigureSerialPort:
设定波特率,数据位,停止位,奇偶校验位,流控制,超时处理,结束符使能,结束符.
特别需要注意的是超时(TIMEOUT)和结束符号两个参数.TIMEOUT默认的10秒,结束符号默认是使能状态,默认的结束符是0X0A(\n),另外,回车0x0D(\r)也经常做为做为结束符号.
如果采用的是二进制通讯,可能会遇到结束符的问题.因为二进制中0A是10,0D是13,这两个是作为数字出现的,如果不禁止结束符号,会导致读提前结束,产生错误的结果,这再和设备通讯时可能会碰到.
至于波特率,数据位等,对照要通讯的设备的要求设定就可以了.
2.VisaWrite:
这个节点负责把缓冲区的数据发送出去,并返回实际发送的数据.
MSCOMM串口通讯时是可以选择文本和二进制方式的,VISA有选择项吗?
没有,完全取决于你的字符串,这是一个需要注意的问题.
正常显示方式时,字符串是"1234"在内存中存储的是ASCII,看下图.
"1"=31,"2"=32 "3"=33,"4"=34.
发送的字符串"1234"实际发送的是16进制的31,32,33,34.用过单片机的都知道,实际所有的串口通讯从本质上说,都是二进制的,只不过接收方面如何判定数据的问题.
比如发送的是33(HEX),接收方面可以解释成数字1,(字符串型),或者是数字33.
用过C的人知道,字符串实际和U8数组是等价的.
所以VISA是不管是否是字符串还是数值,都是采用二进制发送的,关键是我们在于我们的字符串是如何构成的.
VisaRead等其它的几个都比较简单,就不介绍了.