1. Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
  2. Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
  3. Не писать свой вопрос в первую попавшуюся тему - вместо этого создать новую тему.
  4. За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения.
  5. Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
  6. Перед тем как что-то написать - читать здесь и здесь, а студентам - обязательно здесь.
  7. Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.

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

PLC, прочие контроллеры, промышленные компьютеры, операторские панели
Ответить

Автор темы
Strohmann
осмотрелся
осмотрелся
Сообщения: 141
Зарегистрирован: 08 ноя 2010, 14:03
Имя: Владимир
Страна: Россия
город/регион: Новосибирск
Благодарил (а): 9 раз
Поблагодарили: 8 раз

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
P.S. Step 7 v5.5 SP2

khadorik
здесь недавно
здесь недавно
Сообщения: 4
Зарегистрирован: 15 июл 2014, 06:34
Имя: Хадорик Владимир

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

Сообщение khadorik »

На ST в CodeSys как то так, если правильно понял.
[+] Создание Function ArrayOf

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

FUNCTION ArrayOf : BYTE
VAR_INPUT
	ptrDATA:POINTER TO ARRAY [1..2] OF BYTE;
	index : BYTE;
END_VAR
VAR
	i : INT;
END_VAR

i:= 1;
WHILE i < index DO
	ptrDATA := ADR(ptrDATA^[2]);
	i := i + 1;
END_WHILE
ArrayOf := ptrDATA^[1];

[+] Использование

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

arBYTE : ARRAY [1..5] OF BYTE := 5,6,2,1,3;
index : BYTE:=1;
value : BYTE;

value := ArrayOf(ADR(arBYTE),index);
Ответить

Вернуться в «Средний уровень автоматизации (управляющий)»