内容整理于网络:
一、十六进制和ASCII之间的相互转换
有的仪器进行与labview通信,它以十六进制的形式返回信息。例如,它不会返回字母"L”,而是返回它对应的十六进制表示"4C”。在LabVIEW中,我们需要编程实现将这个十六进制表示转换为其对应的ASCII表示实现通信。
将十六进制转换为ASCII:.
为了将一个十六进制的字符串转化为ASCII字符串,您必须首先使用扫描值函数将十六进制字符转化为其对于的十进制表示,您可以在 编程»字符串»字符串/数值转换 函数选板下面找到这个函数。然后再使用强制类型转换来将该十进制表示转换为它对应的ASCII字符串,您可以在 数学»数值»数据操作 函数选板下面找到这个函数。 '
将ASCII转换为十六进制:
为了将一个ASCII字符串转换为十六进制字符串,您必须首先使用强制类型转换函数将ASCII字符串转换为其对应的十进制表示,您可以在数学»数值»数据操作函数选板下面找到这个函数。然后再使用数值至十六进制字符串转换函数将该十进制表示转换为它对应的十六进制字符串,您可以在编程»字符串»字符串/数值转换函数选板下面找到这个函数。
Labview教程链接:http://zone.ni.com/reference/zhs-XX/help/371361J-0118/glang/type_cast/
首先,底层的数据传输都是字节流,所以不管选择什么方式,都会被分解为一个一个的字节。
1选择Hex发送就代表你要发送的内容是纯数字,由程序完成String到Int再到Byte的转化。所以你应该保证每个你要发送的数都是两位的,如果是7就应该写07,因为程序会每两位每两位地读。如果你选择了Hex发送,而输入的又是字符,比如你写了ab,那么就会被程序读为16进制的AB。这就是不同的概念了,无论你选择什么方式显示都不能得到原来的ab了。
2选择ASCII发送就代表你要发送的是字符串,这时候程序就会一位一位地读,比如你写了1234,在字节流中传递的就是123对应的ASCII码,31,32,33,34(十六进制的)。比较而言,在Hex发送模式下,写了1234,会被发送的就是12,34,如果是01020304那就是01,02,03,04。这个时候,你写ab就会发送相应的ASCII码61,62,其他字符同理。
到这里,数据已经发送出去了,接下来就是显示的问题。是显示模式,不是解析,不存在解析。
3选择Hex显示就是把字节转化为16进制整型,你收到的是12,34,就显示为12,34,你收到31,32,33,34,也显示为31,32,33,34,如果收到AB呢,那也是AB。
4选择ASCII显示呢,就会把你接收到的十六进制转化为对应的字符,比如你收到了31,就会显示为1。这种模式下可能会出现乱码,原因就是ASCII码只从0-7f。如果你在十六进制发送模式下发送了字符,比如发送了ab,那你就会收到AB,这个并没有ASCII码对应的字符。
所以在Hex模式下如果输入字符,是无论如何接收不到正确的数据的,其他方式那就随意了。重要的是,方式的选择改变的不是数据本身,而是数据的表现形式。
原文链接:http://blog.csdn.net/wuxinyou1991/article/details/51683627
三、Labview串口发送与接收数据格式的问题
当我在网上搜索串口发送数据格式的问题是会得到这样的结果:labview中发送的是ascll,当你在labview中发送0的时候,在串口助手中会得到48,若想发送十六进制加上字符串到字节数组转换,对于我们新手来说,可能不太理解,我就具体写下来,省得以后忘记。
例子如下:
这样转换以后,会把ascll转换为一个字节的十六进制,后边通过索引数组的分割,然后进行比较,对于后边的常量AA,则为一个字节,可以直接进行比较,但需要右单击,让其16进制显示。这样就是单片机端发送0xAA0xBB0xCC过来的话分别为上边索引数组的0 ,1,2好元素,然后进行处理即可。
上位机发送十六进制给单片机,则格式如下:
先把要发送的十六进制写为常量,同样右单击为16进制显示,然后转换为数组,再通过字节数组到字符串转换,发送给单片机,在单片机接收端即判断缓存区是否有0xaa的数据发来。
原文链接:http://blog.csdn.net/u011123091/article/details/52724616
四、Labview 8.2中实现两台PC间的串口通信
简述
串口通信是使用非常广泛的通信协议之一,一般都是指的RS232,一般PC都会支持串口的,对于速度要求不是特别高的,用串口来通信相对比较简单,而且成本也很低。
关于RS232
RS232常见的9针串口接口,其电平其实是-15V和15V的,-15V貌似表示数据1,而15V表示数据0。而一般单片机的UART接口是使用的TTL电平,0表示低电平,1表示高电平。因此单片机的UART和PC的RS232之间需要有一个转换,有许多成熟的IC可以使用。RS232的通信协议也相对简单。
关于VISA
LabVIEW的VISA模块是用于和外部仪器通信用的,其中有GPIO,串口等等。之前使用过调用MSComm控件的方式,即利用Windows提供的控件对象,在LabVIEW中对该控件的属性和方法进行操作,来实现串口通信。之所以使用MSComm控件,是因为比使用VISA来实现串口通信要灵活一些,比如可以通过回调的方式,在PC的串口buffer中数据字节数到达某一设定值时,可以触发注册好的LabVIEW回调函数来进行处理,这种方式就很好的避免了在轮询中去读取串口数据了,效率提升是很明显的,特别是在速度和数据吞吐率有略高的要求时。
当然了,使用VISA也是可以很简洁的实现串口通信的,其优点就是使用简单,虽然用户体验的简单性往往都会牺牲一些使用上的灵活性。
串口API
VISA一共提供了8个串口API,VISA配置串口API是第一个需要知道的,因为其余所有API使用之前,必须使用这个先。因为PC的串口也和MCU的串口工作原理都是一样的,必须先配置好,并生效,才能使用之。
VISA串口字节数API,因为串口设备一般都会有一个buffer,可以在开发者读出其数据前,将对方的串口设备送过来的数据先暂存在这buffer,而程序开发者需要读取其中数据时,先用这个API看下buffer里面有多少个byte数据,再取出即可。
VISA关闭API,其实LabVIEW中也是占用的PC的某个串口资源的,使用完了,就要关闭掉释放这个资源,可能出了LabVIEW程序,其他的运行于PC的程序偶尔也要用到呢。LabVIEW中有很多这种释放资源的API,大概像进行了malloc,那么用完就得free是一样的道理吧。
VISA清空I/O缓冲区API,作用就是清除掉暂存串口数据的buffer内容,可能有些时候需要丢掉一些数据,用这个API即可。
VISA读取API,显而易见,就是从串口buffer当中读出字节数据了,可以先获取buffer当中字节个数,然后读取对应个数的数据。
VISA串口中断API,这个和MCU的UART中断不是一回事的,是在数据线中设置中断,即两个串口相连,串口1调用该VISA串口中断API设置一次中断,那串口2就会检测到一次数据线中断。不过这个API具体的还没有实际用过。
VISA设置I/O缓冲区大小API,就是设置串口暂存数据buffer的大小,默认好像是无限大,但是那样做还是有风险的,因为PC内存毕竟也有限,如果串口数据一直接收,并一直不读出,那buffer其实会占掉较多内存了吧。所以buffer的大小可以根据自己的需要设置一个适当的值,比较妥当点。
VISA写入API,就是将数据写入串口write buffer咯,然后PC串口硬件检测到write buffer非空时,一个byte一个byte的将数据发出。
实现一个简单的串口助手
用VISA串口API可以实现简单的串口助手工具的,这个很多人都写过的,但是这种方式写的串口助手不高效,在实际使用的时候就能够感觉到的,串口不停的发数据,然后又一边不停的写数据时,很容易卡死的。
串口写
这里其实是通过串口发送仪器的控制指令,用一个UI线程实现即可。外面先调用VISA的配置API,然后在UI线程中完成VISA的写入,最后会将VISA串口资源释放。
串口读
这里其实用了一个队列,来循环的从串口buffer中读取数据,因为VISA串口读取没有中断方式,这里也是导致串口工具效率的最大瓶颈,因此先用一个循环,每隔500ms从串口中读出接收的数据到队列中,这样可以一次读取许多个byte数据,另外循环也不必一直进行,而是有一个500ms的等待,对其余线程的运行还是有些帮助的,当然如果需要不是那么快速,这个500ms等待时间或许还可以设置更长一些。
然后通过阻塞队列,只要队列中有数据了,就从队列中取出数据,用于自己的应用中。
使用VISA串口API,有利有弊。