建议大家按我发帖子的顺序来看,方便大家理解。请不要跳跃式的阅读。很多人现在看书,都跳跃式的看,选择性的看,导致有些细节的部分没有掌握到,然后又因为某个细节耽误很多时间。以上只是个人建议,高手可以略过本帖。
从手把手系列第 1 贴我就写了,用 LabVIEW 来写串口驱动控制仪器,只需要下图的几个函数即可。
事实上,真的只需要下面几个函数。
<ignore_js_op>
所以,LabVIEW 写个串口程序,其实很简单的。 问题是,有很大部分的人,问的就是串口,这个问题,那个问题。没写过串口的人可能会问:你都说了串口很简单啊,就那么几个函数,为什么还有这么多人在问? 我只能回答:不注重细节和自己的程序思维。一般的串口控制结构是: ①配置(打开)串口 ②读写串口 ③关闭串口
我觉得这几个之间,配置 VISA 串口,是个很需要斟酌的部分。配置串口是进入串口通讯的钥匙。首先你配置成功了,才能进行正确的通讯。
下面开始进入正题,先看下 VISA 配置串口函数。 <ignore_js_op>
配置串口时候,最好是在对应的参数端口那里,右键,新建常量或者输入控件,然后再在新建出来的上面修改。因为,新建出来的数据类型,肯定是对的。 <ignore_js_op>
需要注意的是:①停止位那里,不是常数 1 1.5 2 等,实际是 10,15,20 数值。这里最好右键新建常量然后选择对应的枚举类型,如上图所示。 更需要注意的是:②配置串口,顶端有个 启用终止符,一般默认是 真,终止符一般默认是 OA,即换行符。 <ignore_js_op>
有些人接受的字符串,里面含有十六进制的 OA,然后每次数据接收到 OA 就停止了,然后就以为程序有什么问题,其实就是没有配置好 VISA,终止符没有设定为 假。
那为什么配置 VISA 要搞个终止符呢? (注意:这个函数的终止符,只是接受的终止符,只是对 LabVIEW 接收而言,后面会具体讲。) 终止符,是个条件,很多仪器上,也有终止符,而且终止符的优先级高。
比如你要用”VISA 读取“接收 1000 个字符,而还没接受完毕,收到了终止符 OA,那么程序就当一个命令结束了。后面的字符串,放入下一个命令里面去。对编程很方便的,如果你传输的字符不可能出现 OA 或者自己设定的终止符,我建议用终止符来做终止条件,这样,比你在 VISA 读去里读取固定的字节好很多。 <ignore_js_op> <ignore_js_op> 首先看下 VISA 读取帮助。左边输入有个必填参数,叫 VISA 字节总数,你必须指定你要读的字节数。
好了,说到了 VISA 读取,我们顺带看下 VISA 读取。 问题来了,这个字节数怎么确定呢? 一般的组合,如上图所示。 组合的前面,是 VISA 串口字节数,函数路径见上图,其实就是一个属性节点,看那个 bytes at port 英文就应该明白了。
它利用一个读取缓冲区字节数,读到字节数,就确定了 VISA 读取里面那个字节数,然后用读取 VISA 读出来。
意思就是,前面的先侦测下串口缓冲区有多少数据,侦测完了就告诉 VISA 读,VISA就全读出来,。
这个组合的功能是,读取 VISA 串口已有的全部数据。
很多人,也不明白什么意思,看到很多地方这么用,然后自己也这么用。还有的时候,如果是用 MODBUS 协议,你发送一个命令,会回复固定的字节数,这样 VISA 读取那个参数就确定了。 注明一点:串口有个缓冲区,存在计算机内存里,VISA 读取,就是从缓冲区读取数据,读完之后,读取的就不存在缓冲区里了。如果你没读取,那就一直在缓冲区里,直到缓冲区溢出。其实就好比一个水桶,写 VISA 是往水桶进水,读 VISA 是出水。你也可以想想队列的原理,差不多的。
现在看下图。 我用借助串口调试助手和虚拟串口,向 LabVIEW 编写的一个最简单的例子发送字符串。发送的字符串是 010203 0A 050607(十六进制显示)。VISA 串口配置我没都默认,结果我收到的字符串接收到 0A,就终止了。后面的 050607,到了下一次接收了。
这个例子很形象吧。说明了终止符的厉害,默认不配置就是启用终止符,终止符是 OA。 <ignore_js_op> <ignore_js_op> <ignore_js_op> 以上程序,先配置串口,然后循环不停的读串口,用了读取串口字节判断该不该读,当串口有数据,即字节数不位零时,读取串口。
关键词:VISA 配置,停止位,终止符。 深入篇: 以上我们已经讲了 VISA 配置串口函数,熟悉串口通讯的,都应该熟悉这些参数的配置。然后需要注意的:停止位,跟终止符,我也给大家特别说明了。其实,这个函数,也不是最底层的 vi,你可以双击这个 vi,打开子 vi。
程序面板如下: <ignore_js_op> 其实就是属性节点了,只是给出了常用的几个而已。 事实上,有些仪器,我们要配置的可能多一点。这个“VISA 配置串口”函数满足不了要求。
具体配置,看你的仪器说明书,有些可能需要发送终止符, 有些需要握手协议。至于为什么要那些,都是仪器配置问题。自己通讯配置跟仪器一样的就行了。
=================================================== 下面我们以 Keithley 2400 仪器来讲解。这个驱动来源于 NI 官网的仪器驱动。 <ignore_js_op>
我们打开一个例子:Read Single,就是读取单个点的值。例子无所谓,我们今天主要讲的核心是 VISA 串口配置。然后我们点击最开始的 Initialize.vi,就是这个仪器驱动的串口初始化程序。点击去后,如下图所示: <ignore_js_op> 我们分两部分讲,我画了两个圈。 ==================== 第一个圈:首先打开串口,然后清除串口的缓冲,然后,看到了一个属性节点。我们来放大它,看到第一行:timeout.这个是个超时,然后下面有个用户数据,再下面是个串口类型。 <ignore_js_op>
首先,超时是个什么意思呢? LabVIEW 很多地方都有超时,特别是涉及到通信的,TCP 有,串口有,蓝牙有,队列有,通知有。 超时,其实是个约定。 打个比方:男女朋友约会几点见面,然后如果没有加超时,如果一方没来,另一方要一直等一直等,等到天荒地老…
但是,你们可以约定好,如果超过半小时,就不要等我了,说明我不来了。那你过了半小时,就可以走了,说明约会取消。
这个超过半小时,就取消约会。其实就是一个超时设置为半小时。 你也可以想象成打电话,拨对方电话,一分钟过去还没人接,就不再拨打。 你不设置超时,或者超时无限大,如果你读取 VISA,程序就一直在等 VISA 读取,一直等啊等啊,这时候你程序基本属于假死状态了,没救了。。。其他的操作也一样,可能一直等操作完成。
如果你设置了超时,等待超时时间到了,程序就不执行了,错误输出会输出错误。 其次,用户数据是什么意思呢? 其实就是一个变量,存在串口相关的内存里。自己以后变成会用到读取出来进行数据判断。具体怎么用看自己了。 你这里设置了用户数据,可以在后面利用属性节点读取出来。有人肯定要问,我自己设置一个全局变量,其他地方调用,不一样么?回答,不一样,你用这个不更简单么?不需要重新建立变量,而且数据是跟着连线走的。
第三,串口类型是什么? 这个,有些仪器是有 GPIB 接口和 232 接口的,GPIB 接口的需要买 GPIB 卡,使用的方式不一样,但是指令是可以一样的,为了驱动的通用性,就只能用程序判断了,不用人来判断。统自动检测串口类型,执行对应的程序,很智能化吧。 ================================================== 好了,下面是第二个圈的内容。 <ignore_js_op>
这里都是属性节点。会用属性节点的,应该可以找到他们的配置,现在细讲。 ①ASRL End In。这个容易懂,串口接收终止符,这个“VISA 配置串口”函数用的就是 ②ASRL End Out。这个跟接收相对的,串口发送终止符。这个有点特殊。你加了这个后,加入你发送的是 A,如果有这个终止符并且启用的终止符是 B,那么你发送出去的,实际是 AB 两个字节。 ③终止符。这里一般是 OD,也就是回车符,当然你可以自己定义。 ④流控制。这个针对仪器,仪器上有流控制,就跟仪器一样就可以了。具体什么意思,请百度,不需要搞清楚那么多,自己设置和仪器一样就可以了。有 XON/XOFF DTR/DSR各种,跟仪器一样。记得一定要一样的啊。后面就没什么讲的了。
记得注意我红色标注的地方。有些仪器有这么些东西,所以,建议大家仪器,使用 NI 提供的驱动,这样配置方面就不需要自己想太多,因为别人都配置好了。
有人可能会问,这些属性节点怎么来的? 见下图,当然,你也可以在应用程序那个属性节点,连接到 VISA 引用,也可以得到。 <ignore_js_op>
点击选择对应的属性。 <ignore_js_op> 好了,串口配置就讲完了。