Как я могу записать упакованные числа BCD на старый инструмент (Varian FR41 Gaussmeter) с LabVIEW? - PullRequest
1 голос
/ 02 ноября 2019

В настоящее время я пытаюсь установить связь со старым прибором, который использует только упакованные числа BCD (это, если кому-то, знакомый, гауссметр контроллера Varian FR41). Я использую LabVIEW для репликации старого кода C, который выводит код BCD. Ниже приведен сценарий Си. Он выполняет простую арифметику для генерации целых чисел, которые экспортируются в прибор через порт IEEE с использованием %c.

#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

Данные передаются на FR-41 в виде последовательности из трех 8-битных байтов. Каждый байт разделен на два полубайта, hi и lo, которые могут содержать только цифры BCD. Когда используется вспомогательный выходной порт, четвертый байт (любое двоичное число) добавляется в начало последовательности. Последний отправленный символ содержит наименьшую значащую цифру (LSD) новой установки Гаусса в расположении байта hi и символ NCD BCD управления загрузкой (bin 14) в младшем байте, который интерпретируется для загрузки всех регистров с новыми данными. Один бит младшего байта контролирует превышение 10 кГс при использовании. никаких изменений настроек не происходит, пока не получено управляющее слово.

Итак, если я правильно понимаю это в приведенном выше коде C, первый добавленный байт (вспомогательный порт вывода) кажетсябыть 7, который должен быть 0000 0111 в BCD. Следующие байты, для записи 2510.8, должны быть 0010 0101 0001 0000 1000, за которыми следует 1110 (для контрольного слова корзины 14).

Вот что я сделал. Используя прикрепленный файл .VI, я могу воспроизвести 32-битную строку BCD, которая, как я ожидаю, должна быть. Я отправляю это на VI Послания GPIB в LabVIEW (я также пытался использовать VISA Write, но, насколько я вижу, он делает одно и то же во всех тестах). Однако инструмент не регистрирует ничего происходящего.

Интересно то, что когда я посылаю инструменту информацию в виде %f строки с плавающей точкой, то есть, 7.0000142.00037.00016.000, инструмент регистрирует что-то происходящее и меняются десятки и сотни мест. Итак, если я отправлю 42 в качестве плавающей запятой, прибор перейдет к настройке Гаусса X4X2.X. Если я поставлю 142, он сделает то же самое. Если я поставлю 17, он перейдет к настройке X1X7.X. Если я отправлю 17, то 25 займет только первое.

Я думаю, что что-то в Посылке GPIB или VISA Write берет мою строку чисел BCD и отправляет их как-то еще, но я не могу понять, что я могу делать неправильно. Любая помощь или тесты будут высоко оценены;Я боролся с этим уже несколько недель, но безрезультатно. VI for reproducing the C script copied above

1 Ответ

3 голосов
/ 02 ноября 2019

Как вы написали, значение 2510.8 должно быть отправлено с начальным байтом значения 7 и отрывком управляющего хвоста значения 14 как

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

Но вы должны отправитьровно 4 байта, а не эта длинная строка.

Так же, как подсказка: в шестнадцатеричном представлении выше указано

0x0725108E

Обратите внимание, что 2510.8 выглядит как 25108 здесь. Это магия BCD.


Теперь мне понадобилось время, чтобы понять ваш код LV. Наконец, вы конвертируете это значение 2510,8 в строку "2510.8", а затем извлекаете цифры.

Первая проблема: вы извлекаете строку длины 1 с начала (= "2") для z1строка длиной 2 с начала (= "25") для z2, строка длиной 3 с начала (= "251") для z3 ... (= "2510") для z4. Вам необходимо увеличить начальную позицию и сохранить длину = 1 для метода подстроки.

Второе: вы пытаетесь отформатировать значения как двоичные в строку.

Следующий код преобразует значениеб в нужную строку. (Это фрагмент ВП, то есть: Откройте новый ВП и перетащите эту картинку с этого сайта прямо в окно блок-схемы!)

enter image description here

Подробно:

  • Умножьте b на 10, чтобы сделать его целым числом
  • Разделите на 10 пять раз в цикле и создайте массив остатков.
    Остаткиэто клочки!
  • изменить направление массива и добавить 14 в качестве последнего куска.
  • изменить как 2D-массив, поэтому в каждом ряду выделяется верхний и нижний клочок
  • цикл по строкам, построение байтов левого и правого столбцов (верхний и нижний полубайт)
  • Вставка байта 7 в начало нового массива
  • с использованием ByteArrayToStringчтобы получить то, что вам нужно отправить на устройство

Примечание:

  • Это одно из решений, наверняка есть более быстрые и лучшие. Но это легко.
  • Это решение может преобразовать любое (целое) число в BCD, в то время как C-код очень специфичен для этого единственного варианта использования
  • U8 в первом цикле необходимТак как функция ToString может также преобразовывать 4-байтовые числовые переменные в 4-байтовые строки, но нам нужно 1 байт.
  • Индикатор BCD Bytes был установлен для отображения в виде HEX, это не имеет никакого отношения к значениям
  • Строковый индикатор показывает 4 загадочных байта, поскольку не все байты являются символами ASCII. Это полностью нормально!
...