我如何使用Labview将打包的BCD编号写入旧仪器(Varian FR41高斯计?

问题描述 投票:0回答:1

我目前正在尝试与仅使用打包BCD编号的旧仪器通信(如果熟悉的话,这是Varian FR41控制器高斯计)。我正在使用Labview复制一些输出BCD代码的旧C代码。下面是C脚本。它正在做的是一些简单的算法,以生成整数,并使用%c通过IEEE端口将其导出到仪器。

#include "ieeeio.h"
#include <math.h>
#include <stdio.h>


main()

{
  long  temp;
  int   z1,z2,z3,z4,b1,b2,b3;
  float b;
  double gauss,hv=5000.,magconst=.069,Mass=87.;

  if (ieeeinit()==-1)
  {
    printf("Cannot initialize IEEE system.\n");
    exit(1);
  }
  gauss=sqrt(Mass*hv/magconst);
  temp=10*gauss;
  b=temp/10.;
  z1=b/1000;
  z2=b/100;
  z3=b/10;
  z4=b;
  printf("\n\r %f %f %d %d %d %d",gauss,b,z1,z2,z3,z4);
  b1=z2+z1*6;
  b2=z4+6*z3-160*z2;
  b3=(b-z4)*160+14;
  printf("\n\r %d %d %d %d",7,b1,b2,b3);
  ieeewt("output 08;");
  ieeeprtf("%c%c%c%c\n",7,b1,b2,b3);
}

我已经生成了一个.VI,它生成了相同的数字b1,b2,b3,并将它们放入打包的BCD数字字符串中。使用上面的输入变量HV,magconst,mass,输出应为2510.8高斯。和b1,b2,b3分别是142,37,16

现在了解瓦里安高斯计的要求。这是描述仪器如何接收信息的文字(并非所有信息都是有用的,但出于完整性考虑,我将其复制)。我还要附加显示BCD格式的原理图图像。 Format for BCD from manual

数据作为三个8位字节的序列发送到FR-41。每个字节分为两个半字节hi和lo,它们只能包含BCD编号。使用辅助输出端口时,第四个字节(任何二进制数)将添加到序列的开头。发送的最后一个字符在hi字节位置包含新高斯设置的最低有效数字(LSD),在lo字节中包含一个加载控制NON BCD字符(bin 14),该字符被解释为用新数据加载所有寄存器。 lo字节的一位在使用时控制10 kGauss超范围。在接收到控制字之前,不会更改设置。

因此,如果我在上面的C代码中正确理解了这一点,则添加的第一个字节(辅助输出端口)似乎是7,在BCD中应为0000 0111。接下来的字节(写入2510.8)应该是0010 0101 0001 0000 1000,然后是1110(用于bin 14控制字)。

这是我所做的。使用附带的.VI,我可以再现我期望的32位BCD字符串。我将其发送到Labview中的GPIB发送消息VI(我也尝试使用VISA Write,但据我所知,它在所有测试中都做同样的事情)。但是,该仪器不会记录任何事件。

[有趣的是,当我以%f字符串的形式将浮点数作为信息发送给仪器时,仪器7.0000142.00037.00016.000会记录正在发生的事情,并且数十个位置会改变。因此,如果我发送42作为浮点,则乐器将进入X4X2.X高斯设置。如果我输入142,它将执行相同的操作。如果输入17,它将转到X1X7.X设置。如果我将其发送给17,则它将仅接收第一个。

[我的想法是,GPIB发送或VISA写入中的某些内容正在占用我的BCD字符串,并将其作为其他内容发送出去,但是我无法弄清楚我可能做错了什么。任何帮助或测试将不胜感激;我已经为此苦苦挣扎了好几个星期了。 25

labview bcd packed
1个回答
0
投票

正如您所写,值2510.8应该以值7的前导字节和值14的尾部控制半字节发送为

VI for reproducing the C script copied above

但是您应该发送的正是4个字节,而不是这个长字符串。

仅作为提示:以上以十六进制表示的是

0000'0111 0010'0101 0001'0000 1000'1110

请注意2510.8在此处显示为25108的方式。这就是BCD的魔力。


现在,我花了一些时间来了解您的LV代码。最后,您将2510.8的值转换为字符串0x0725108E,然后提取数字。

[第一个问题:对于"2510.8",您从头开始(= "2")提取长度为1的字符串,对于z1,从中头开始提取(= "25")长度为2的字符串,长度为3的字符串从头开始(= z2)代表"251" ...(= z3)代表"2510"。您需要增加起始位置,并保持子字符串方法的长度= 1。

第二:您尝试将值格式化为二进制格式为字符串。

以下代码将值b转换为所需的字符串。(这是一个VI片段,即:打开一个新的VI,并将该图片从该网站直接拖到程序框图窗口中!)

z4

详细:

  • 将b乘以10使其成为整数
  • 在一个循环中除以10 5次,并创建余数数组。剩下的就是蚕食了!
  • 还原数组的方向,并在最后的半字节处附加enter image description here
  • 重塑为2D数组,因此每行分别代表上下半字节
  • 循环遍历,建立左右列的字节(上下半字节)
  • 在新数组的开头插入字节14
  • 使用ByteArrayToString获取需要发送到设备的内容

注意:

  • 这是一个解决方案,肯定有更快更好的解决方案。但这很容易。
  • 此解决方案可以将任何(整数)数字转换为BCD,而C代码非常特定于此单个用例
  • 第一个循环中的U8是必需的,因为ToString函数也可以将4byte的数字变量转换为4byte的字符串,但是我们需要1byte。
  • [BCD字节数指示器已设置为显示为十六进制,与值无关
  • 字符串指示器显示4个加密字节,因为并非所有字节都是ASCII字符。完全可以!
© www.soinside.com 2019 - 2024. All rights reserved.