STL Можно ли в FC передать указатель на начало массива в DB?

Инженерное программное обеспечение
Ответить
Strohmann
Дилетант
Сообщения: 23
Зарегистрирован: 26 апр 2014, 05:58

STL Можно ли в FC передать указатель на начало массива в DB?

Сообщение Strohmann »

Добрый день, товарищи.

Пишу функцию для доступа к элементу массива по переменному индексу.
Но не могу понять, как передать указатель на начало массива в функцию, как входной параметр блока.
Функция с загрузкой указателя напрямую работает. Прошу помочь мне разобраться, как можно передать адрес начала массива. Идеальным вариантом было бы получение адреса через символьное имя массива.

pArrayBegining объявлен как входной параметр типа указатель
Пробовал несколько способов передачи указателя:

1) L pArrayBegining - получаю ошибку "Variable of a higher type cannot be used in this statement"
2) L P##pArrayBegining - Какая-то ерунда в AR1: 2#1000_0111_0000_0000_0000_0000_1010_1000. Если проанализировать: 2#[1](признак межзонного указателя)000_0[111](операнд область)_[0000_0000_0000_0000_1010_1](0..010101 - смещение в байтах - 21)[000](смещение в битах - 0). Но я-то передаю указатель P#254.0 =(
3) L P#254.0; получаю желаемый результат AR1 = 2#0000_0000_0000_0000_0000_0111_1111_0000
Source

Код: Выделить всё

FUNCTION "WriteDBXtoArray" : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  dbTargetDB : BLOCK_DB ;	//DB, в которой находится целевой массив
  pArrayBegining : POINTER ;	//Указатель на начало массива
  iIndexArray : INT ;	//Индекс элемента массива, который будет записан
END_VAR
VAR_OUTPUT
  diAR1 : DINT ;	//для проверки сохранить указатель на начало массива
END_VAR
VAR_TEMP
  diSavedAR1 : DINT ;	//Сохранённое значение регистра AR1
  iByteOffset : INT ;	//Количество байт для смещения
  iBitOffset : INT ;	//Количество бит для смещения
END_VAR
BEGIN
NETWORK
TITLE =

// Расчёт смещения
      L     #iIndexArray; 
// <!!! для теста !!!>
      INC   1; 
// </!!! для теста !!!>
      L     8; 
      /I    ; 
      T     #iByteOffset; // частное деления из ACCU1-L
      SRD   16; // сдвиг ACCU1-H (остаток от деления) в ACCU1-L
      T     #iBitOffset; 

      TAR1  #diSavedAR1; // сохраняем значение регистра AR1
//Так как В  функциях  FC  адрес  параметра  блока  не  может  быть  загружен непосредственно в адресный регистр:
//      L     pArrayBegining //Err: Variable of a higher type cannot be used in this statement
//      L     P##pArrayBegining           //Какая-то ерунда в AR1: 2#1000_0111_0000_0000_0000_0000_1010_1000
      L     P#254.0; // желаемый результат AR1 =  2#0000_0000_0000_0000_0000_0111_1111_0000
      LAR1  ; // загружаем area-pointer начала массива 
// <!!! для теста !!!>
      TAR1  ; 
      T     #diAR1; 
// </!!! для теста !!!>

// загружаем смещение в байта в регистр AR1
      L     #iByteOffset; 
      SLW   3; // сдвигаем смещение в байтах влево, так как AR1 32 бита [ххх .. 16бит - адрес байта, 3бит - адрес бита]
      +AR1  ; 
// загружаем смещение в битах в регистр AR1
      L     #iBitOffset; 
      +AR1  ; 
// чтение требуемого бита
      OPN   #dbTargetDB; // открываем требуемый блок данных  
      SET   ; 
      S     DBX [AR1,P#0.0]; // устанавливаем требуемый бит

      LAR1  #diSavedAR1; // восстанавливаем содержимое регистра AR1
END_FUNCTION

Ответить