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

S7-300, запись размера блока данных

ПЛК SIMATIC (S7-200, S7-1200, S7-300, S7-400, S7-1500, ET200)

Модератор: Глоб.модераторы

Ответить

Автор темы
tonyk
осмотрелся
осмотрелся
Сообщения: 106
Зарегистрирован: 16 дек 2018, 16:35
Имя: Антон
Благодарил (а): 5 раз
Поблагодарили: 4 раза

S7-300, запись размера блока данных

Сообщение tonyk »

Коллеги!
Подскажите, пожалуйста, как указать размера данных для копирования.

Есть FB, которому передаётся номер DB.
Внутри FB есть строка:

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

VAR
 ...    
    request : STRING[ 8 ];
 ...
END_VAR
После формирования строки её нужно переместить в DB1010, для этого вызывается BLKMOV. Прямой вызов работает нормально:

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

                l := BLKMOV
                        ( 
                            SRCBLK := request, 
                            DSTBLK := DВ1010                        
                        );
А вот вызов через номер блока- нет. Как указать количество байт вместо "???", которые нужно переместить?

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

                l := BLKMOV
                        ( 
                            SRCBLK := request, 
                            DSTBLK := WORD_TO_BLOCK_DB( INT_TO_WORD( request_BN ) )???                    
                        );
У вас нет необходимых прав для просмотра вложений в этом сообщении.

SMax
не первый раз у нас
не первый раз у нас
Сообщения: 325
Зарегистрирован: 17 июн 2016, 14:18
Имя: Максим
Благодарил (а): 7 раз
Поблагодарили: 118 раз

S7-300, запись размера блока данных

Сообщение SMax »


Автор темы
tonyk
осмотрелся
осмотрелся
Сообщения: 106
Зарегистрирован: 16 дек 2018, 16:35
Имя: Антон
Благодарил (а): 5 раз
Поблагодарили: 4 раза

S7-300, запись размера блока данных

Сообщение tonyk »

SMax писал(а): 31 янв 2023, 10:00 https://support.industry.siemens.com/fo ... -db/153307
В заметке по ссылке нет указаний о передаче размера.
В STL это указывается так:
У вас нет необходимых прав для просмотра вложений в этом сообщении.

SMax
не первый раз у нас
не первый раз у нас
Сообщения: 325
Зарегистрирован: 17 июн 2016, 14:18
Имя: Максим
Благодарил (а): 7 раз
Поблагодарили: 118 раз

S7-300, запись размера блока данных

Сообщение SMax »

Ну тогда как-то так:
[+] Код

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

FUNCTION_BLOCK FB55

VAR_INPUT
    request_BN : INT;
END_VAR

VAR_TEMP
    pDST : ANY;
    pAnyDST AT pDST :
    STRUCT // Diassembled ANY pointer structure
        S7Code : BYTE; // Code for S7 (fixed at 16#10)
        DataType : BYTE; // Code for data type
        Length : INT; // Repetition factor = Send/receive length
        DBNumber : INT; // Data block Number
        MemoryArea : BYTE; // Specified memory area
        ByteAddressMSB : BYTE; // Byte address most significant bits
        ByteAddressLSB : WORD; // Byte address least significant bits
    END_STRUCT;
    l : INT;
END_VAR

VAR
    request : STRING[8];
END_VAR

pAnyDST.S7Code := 16#10;
pAnyDST.DataType := 16#02;
pAnyDST.Length := 32;
pAnyDST.DBNumber := request_BN;
pAnyDST.MemoryArea := 16#84;
pAnyDST.ByteAddressMSB := 0;
pAnyDST.ByteAddressLSB := INT_TO_WORD(780*8);

    l := BLKMOV(SRCBLK := request, DSTBLK := pDST);

END_FUNCTION_BLOCK
см. https://support.industry.siemens.com/fo ... -scl/65082

Автор темы
tonyk
осмотрелся
осмотрелся
Сообщения: 106
Зарегистрирован: 16 дек 2018, 16:35
Имя: Антон
Благодарил (а): 5 раз
Поблагодарили: 4 раза

S7-300, запись размера блока данных

Сообщение tonyk »

SMax, получилось! Заработало!

Можно пояснить, откуда взят дизассемблер и значегия для pANY?

И сломалось. Странно. Может, я чё-то не так сделал? Для чистоты эксперимента всего лишь пересобрал и перезалил проект.

SMax
не первый раз у нас
не первый раз у нас
Сообщения: 325
Зарегистрирован: 17 июн 2016, 14:18
Имя: Максим
Благодарил (а): 7 раз
Поблагодарили: 118 раз

S7-300, запись размера блока данных

Сообщение SMax »

tonyk писал(а): 31 янв 2023, 14:50 Можно пояснить, откуда взят дизассемблер и значегия для pANY?
Что Вы имеете ввиду под дизассемблер, тут ничего не дизассемблировалось.
Значения для pANY взяты из примера по ссылке, а вообще смотрите структуру указателей, например у Бергера.
0001.jpg
Отправлено спустя 21 минуту 58 секунд:
tonyk писал(а): 31 янв 2023, 14:50И сломалось.
Я Вам дал только пример, его еще нужно допилить под себя.
Попробуйте заменить:

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

pAnyDST.ByteAddressLSB := INT_TO_WORD(780*8);
на

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

pAnyDST.ByteAddressLSB := 16#0;
У вас нет необходимых прав для просмотра вложений в этом сообщении.

Автор темы
tonyk
осмотрелся
осмотрелся
Сообщения: 106
Зарегистрирован: 16 дек 2018, 16:35
Имя: Антон
Благодарил (а): 5 раз
Поблагодарили: 4 раза

S7-300, запись размера блока данных

Сообщение tonyk »

SMax писал(а): 31 янв 2023, 17:03 pAnyDST.ByteAddressLSB := 16#0;
Вот это заработало. Откуда это взялось- понял, почитав Бергера. Благодарю за помощь!

Раз уж встретил знающего человека, тогда позволю себе задать ещё один вопрос. С каждым FB обычно связан экземплярный DB. Для вызова некоторых библиотечных FB требуется передавать им номер DB, например, как того требуют SEND и RCV в моём случае. Вопрос: как мне получить номер экземплярного DB у экземпляра моего FB, чтобы адресоваться к этому экземплярному DB и передать его номер другим FB? Если это есть у того же Бергера и я не понял, что это ответ на мой вопрос, можно просто указать страницу для прочтения.
У вас нет необходимых прав для просмотра вложений в этом сообщении.

stesl
эксперт
эксперт
Сообщения: 1035
Зарегистрирован: 31 мар 2018, 12:05
Имя: Вячеслав
Благодарил (а): 100 раз
Поблагодарили: 141 раз

S7-300, запись размера блока данных

Сообщение stesl »

tonyk писал(а): 01 фев 2023, 08:37 как мне получить номер экземплярного DB у экземпляра моего FB, чтобы адресоваться к этому экземплярному DB и передать его номер другим FB?
Конкретно так не пробовал. Но Вам вообще известно о методе мультиэкземплярных FB? Когда кучка FB собирается в одном каком то FB, и уже при вызове оного формируется один большой DB для всех этих FB. Я бы так решил озвученную задачу.
Если, конечно, правильно понял ))

Автор темы
tonyk
осмотрелся
осмотрелся
Сообщения: 106
Зарегистрирован: 16 дек 2018, 16:35
Имя: Антон
Благодарил (а): 5 раз
Поблагодарили: 4 раза

S7-300, запись размера блока данных

Сообщение tonyk »

stesl писал(а): 01 фев 2023, 09:07 же при вызове оного формируется один большой DB для всех этих FB
И как узнать номер этого DB и положение данных для моего FB? Вот в чём вопрос.

stesl
эксперт
эксперт
Сообщения: 1035
Зарегистрирован: 31 мар 2018, 12:05
Имя: Вячеслав
Благодарил (а): 100 раз
Поблагодарили: 141 раз

S7-300, запись размера блока данных

Сообщение stesl »

tonyk писал(а): 01 фев 2023, 09:57 И как узнать номер этого DB и положение данных для моего FB
Предлагаю сперва изучить предмет )) Возможно ответ придет после понимания.
Вкратце - зачем Вам номер DB? Номер может быть константой, смещение тоже, поскольку DB (набор данных) по размеру - един. Указывать можно только величину смещения.

Автор темы
tonyk
осмотрелся
осмотрелся
Сообщения: 106
Зарегистрирован: 16 дек 2018, 16:35
Имя: Антон
Благодарил (а): 5 раз
Поблагодарили: 4 раза

S7-300, запись размера блока данных

Сообщение tonyk »

stesl писал(а): 01 фев 2023, 10:08 Вкратце - зачем Вам номер DB?
Номер DB нужен для передачи его другим FB, которые его требуют для своей работы, например, линейка 1SI для работы с последовательными интерфейсами 232, 422 и 485 по разным протоколам.
У вас нет необходимых прав для просмотра вложений в этом сообщении.

SMax
не первый раз у нас
не первый раз у нас
Сообщения: 325
Зарегистрирован: 17 июн 2016, 14:18
Имя: Максим
Благодарил (а): 7 раз
Поблагодарили: 118 раз

S7-300, запись размера блока данных

Сообщение SMax »

Смотрите DINO, это в STL.
Как это сделать в SCL не знаю, копайте форум Siemens.

Отправлено спустя 14 минут 44 секунды:
Хотя, вот так вроде работает:
[+] Код

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

FUNCTION_BLOCK FB56

VAR_OUTPUT
    DB_Num : INT;
END_VAR

VAR_TEMP
    pDST : ANY;
    pAnyDST AT pDST :
    STRUCT // Diassembled ANY pointer structure
        S7Code : BYTE; // Code for S7 (fixed at 16#10)
        DataType : BYTE; // Code for data type
        Length : INT; // Repetition factor = Send/receive length
        DBNumber : INT; // Data block Number
        MemoryArea : BYTE; // Specified memory area
        ByteAddressMSB : BYTE; // Byte address most significant bits
        ByteAddressLSB : WORD; // Byte address least significant bits
    END_STRUCT;
END_VAR

VAR
    DBHelpVar : BOOL;
END_VAR

pDST := DBHelpVar;
DB_Num := pAnyDST.DBNumber;
    
END_FUNCTION_BLOCK

stesl
эксперт
эксперт
Сообщения: 1035
Зарегистрирован: 31 мар 2018, 12:05
Имя: Вячеслав
Благодарил (а): 100 раз
Поблагодарили: 141 раз

S7-300, запись размера блока данных

Сообщение stesl »

tonyk писал(а): 01 фев 2023, 10:19 Номер DB нужен для передачи его другим FB
Сути не понимаете... Все нужные Вам FB можно собрать в другой общий FB. И уже у него будет DB. Таким образом у всех FB, DB будет один, но большой. Там будут данные всех этих FB. А, ладно короче, проще уже рассказать как это делается. Но там вкратце не получится.

PS так, повнимательнее посмотрел на Вашу ф-цию - таки да. Тут не пролезет. Как я понимаю тут нужен стандартный какой то DB и указывается только его номер. Обычно для этого используется указатель. Ну я с такими FB по связи пока только встречался

PPS Хотя... Есть же DBB, а это и есть смещение. А значит прокатит!

Автор темы
tonyk
осмотрелся
осмотрелся
Сообщения: 106
Зарегистрирован: 16 дек 2018, 16:35
Имя: Антон
Благодарил (а): 5 раз
Поблагодарили: 4 раза

S7-300, запись размера блока данных

Сообщение tonyk »

Осталось понять, как узнать смещение переменной внутри DB. Лобовое использование значения из поля
SMax писал(а): 01 фев 2023, 10:49 ByteAddressLSB : WORD; // Byte address least significant bits
не срабатывает. Если подставить смещение вручную, то работает.

SMax
не первый раз у нас
не первый раз у нас
Сообщения: 325
Зарегистрирован: 17 июн 2016, 14:18
Имя: Максим
Благодарил (а): 7 раз
Поблагодарили: 118 раз

S7-300, запись размера блока данных

Сообщение SMax »

tonyk писал(а): 01 фев 2023, 13:08 Осталось понять, как узнать смещение переменной внутри DB
Какое у Вас смещение?

Отправлено спустя 1 минуту 4 секунды:
С номером DB разобрались?

Автор темы
tonyk
осмотрелся
осмотрелся
Сообщения: 106
Зарегистрирован: 16 дек 2018, 16:35
Имя: Антон
Благодарил (а): 5 раз
Поблагодарили: 4 раза

S7-300, запись размера блока данных

Сообщение tonyk »

SMax писал(а): 01 фев 2023, 13:21 С номером DB разобрались?
Да. Номер передаётся правильно.
Смещение 543, хотя показывает 542. Кстати, и длину пришлось увеличить на 1, чтобы строка вся передавалась.
У вас нет необходимых прав для просмотра вложений в этом сообщении.

SMax
не первый раз у нас
не первый раз у нас
Сообщения: 325
Зарегистрирован: 17 июн 2016, 14:18
Имя: Максим
Благодарил (а): 7 раз
Поблагодарили: 118 раз

S7-300, запись размера блока данных

Сообщение SMax »

0002.jpg
Длина STRING[8] составляет 10 байт, 8 задекларированных и 2 служебных байта заголовка.
С чем связано 542/543, возможно с этими-же заголовочными байтами.

Для получения смещения, можете преобразовывать так:
(компилятор ошибок не дает, а что там по факту не проверял)

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

//offset : DWORD

offset := SHL(IN := BYTE_TO_DWORD(pAnyDST.ByteAddressMSB), N := 16);
offset := offset OR WORD_TO_DWORD(pAnyDST.ByteAddressLSB);
offset := SHR(IN := offset, N := 3);
У вас нет необходимых прав для просмотра вложений в этом сообщении.

zero
здесь недавно
здесь недавно
Сообщения: 7
Зарегистрирован: 07 мар 2021, 17:55
Имя: Иванн

S7-300, запись размера блока данных

Сообщение zero »

Помогите пжлст. SCL
Хочу в оргблоке копировать локальные переменные в ДБ, при вызове ОБ. С помощью BLKMOV ну жно скопировать первые 12 байт локальных данных в первые 12 байт DB82.
BLKMOV дает ошибку 0х8124 и ничего не копирует.
Хотя вроде все правильно кмк. ОБ вызывается совершенно точно, дату-время пишет и обычный MOVE копирует.
[+]
ORGANIZATION_BLOCK OB82
TITLE = 'Diagnostic Interrupt'

VAR_TEMP
OB82_EV_CLASS : BYTE;
OB82_FLT_ID : BYTE;
OB82_PRIORITY : BYTE;
OB82_OB_NUMBR : BYTE;
OB82_RESERVED_1 : BYTE;
OB82_IO_FLAG : BYTE;
OB82_MDL_ADDR : INT;
OB82_MDL_DEFECT : BOOL;
OB82_INT_FAULT : BOOL;
OB82_EXT_FAULT : BOOL;
OB82_PNT_INFO : BOOL;
OB82_EXT_VOLTAGE : BOOL;
OB82_FLD_CONNCTR : BOOL;
OB82_NO_CONFIG : BOOL;
OB82_CONFIG_ERR : BOOL;
OB82_MDL_TYPE : BYTE;
OB82_SUB_MDL_ERR : BOOL;
OB82_COMM_FAULT : BOOL;
OB82_MDL_STOP : BOOL;
OB82_WTCH_DOG_FLT : BOOL;
OB82_INT_PS_FLT : BOOL;
OB82_PRIM_BATT_FLT : BOOL;
OB82_BCKUP_BATT_FLT : BOOL;
OB82_RESERVED_2 : BOOL;
OB82_RACK_FLT : BOOL;
OB82_PROC_FLT : BOOL;
OB82_EPROM_FLT : BOOL;
OB82_RAM_FLT : BOOL;
OB82_ADU_FLT : BOOL;
OB82_FUSE_FLT : BOOL;
OB82_HW_INTR_FLT : BOOL;
OB82_RESERVED_3 : BOOL;
OB82_DATE_TIME : DATE_AND_TIME;

pDST : ANY;
pAnyDST AT pDST :
STRUCT
S7Code : BYTE;
DataType : BYTE;
Length : INT;
DBNumber : INT;
MemoryArea : BYTE;
ByteAddressMSB : BYTE;
ByteAddressLSB : WORD;
END_STRUCT;

pSRC : ANY;
pAnySRC AT pSRC :
STRUCT
S7Code : BYTE;
DataType : BYTE;
Length : INT;
DBNumber : INT;
MemoryArea : BYTE;
ByteAddressMSB : BYTE;
ByteAddressLSB : WORD;
END_STRUCT;
END_VAR

BEGIN

pAnySRC.S7Code := 16#10; // S7Code member is fixed at 16#10
pAnySRC.DataType := 16#02; // BYTE Data type
pAnySRC.Length := 12;
pAnySRC.DBNumber := 0; // DB Number, Для L возможно нужен ноль???? Вот тут я не уверен
pAnySRC.MemoryArea := 16#86; // 16#86=Local data (L stack)
pAnySRC.ByteAddressMSB := 0; // Generally, you can leave pAny.ByteAddressMSB at zero unless you are using very large DB's (greater than 8192 bytes)
pAnySRC.ByteAddressLSB := W#0;

pAnyDST.S7Code := 16#10;
pAnyDST.DataType := 16#02;
pAnyDST.Length := 12;
pAnyDST.DBNumber := 82;
pAnyDST.MemoryArea := 16#84;
pAnyDST.ByteAddressMSB := 0;
pAnyDST.ByteAddressLSB := W#0;

DB82.OB82_TMP := BLKMOV(SRCBLK := pSRC, DSTBLK => pDST);
DB82.OB82_DATE := FC49(OB82_DATE_TIME);
DB82.OB82_TIME := FC8(OB82_DATE_TIME);

END_ORGANIZATION_BLOCK
Структура ДБ
[+]
DATA_BLOCK DB82

STRUCT
OB82_EV_CLASS : BYTE; //Класс события и идентификаторы
OB82_FLT_ID : BYTE;
OB82_PRIORITY : BYTE;
OB82_OB_NUMBR : BYTE;
OB82_RESERVED_1 : BYTE;
OB82_IO_FLAG : BYTE;
OB82_MDL_ADDR : INT; //Базовый логический адрес модуля, в котором произошел отказ
OB82_MDL_DEFECT : BOOL;
OB82_INT_FAULT : BOOL;
OB82_EXT_FAULT : BOOL;
OB82_PNT_INFO : BOOL;
OB82_EXT_VOLTAGE : BOOL;
OB82_FLD_CONNCTR : BOOL;
OB82_NO_CONFIG : BOOL;
OB82_CONFIG_ERR : BOOL;
OB82_MDL_TYPE : BYTE;
OB82_SUB_MDL_ERR : BOOL;
OB82_COMM_FAULT : BOOL;
OB82_MDL_STOP : BOOL;
OB82_WTCH_DOG_FLT : BOOL;
OB82_INT_PS_FLT : BOOL;
OB82_PRIM_BATT_FLT : BOOL;
OB82_BCKUP_BATT_FLT : BOOL;
OB82_RESERVED_2 : BOOL;
OB82_RACK_FLT : BOOL;
OB82_PROC_FLT : BOOL;
OB82_EPROM_FLT : BOOL;
OB82_RAM_FLT : BOOL;
OB82_ADU_FLT : BOOL;
OB82_FUSE_FLT : BOOL;
OB82_HW_INTR_FLT : BOOL;
OB82_RESERVED_3 : BOOL;
OB82_DATE : DATE;
OB82_TIME : TIME_OF_DAY;
OB82_TMP : INT;
END_STRUCT
BEGIN

END_DATA_BLOCK

AppCreator
здесь недавно
здесь недавно
Сообщения: 35
Зарегистрирован: 02 фев 2023, 10:38
Имя: Владимир
Страна: РФ
город/регион: Восьмипалатинск
Благодарил (а): 4 раза
Поблагодарили: 12 раз

S7-300, запись размера блока данных

Сообщение AppCreator »

Если у Вас нет уверенности, как заполнить переменную типа ANY - просто дайте это сделать компилятору:

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

pSRC:=OB82_EV_CLASS;  //первая переменная из передаваемой области; обратите внимание на тип данных переменной для следующей строки кода
pAnySRC.Length := 12;

pDST:=DB82.OB82_EV_CLASS; //первая переменная из области назначения;  обратите внимание на тип данных переменной для следующей строки кода
pAnyDST.Length := 12;

DB82.OB82_TMP := BLKMOV(SRCBLK := pSRC, DSTBLK => pDST);


zero
здесь недавно
здесь недавно
Сообщения: 7
Зарегистрирован: 07 мар 2021, 17:55
Имя: Иванн

S7-300, запись размера блока данных

Сообщение zero »

AppCreator писал(а): 02 фев 2023, 10:46 Если у Вас нет уверенности, как заполнить переменную типа ANY - просто дайте это сделать компилятору:
Гениально. Все работает. Очень много спасибо, я с этими указателями уже мозг почти сломал :crazy0to:
А pAnySRC.Length := 12 это длина в единицах типа, который имеет пременная pSRC:=OB82_EV_CLASS?
т.е. если pSRC я установлю на переменную типа DWORD, то 12 будет длина в DWORDах?

AppCreator
здесь недавно
здесь недавно
Сообщения: 35
Зарегистрирован: 02 фев 2023, 10:38
Имя: Владимир
Страна: РФ
город/регион: Восьмипалатинск
Благодарил (а): 4 раза
Поблагодарили: 12 раз

S7-300, запись размера блока данных

Сообщение AppCreator »

Да, все верно. ANY формируется в соответствии с переменной, на которую он указывает (адресная область, тип данных, количество данных этого типа, начальный адрес), а дальше просто корректируем указатель под свои цели

Автор темы
tonyk
осмотрелся
осмотрелся
Сообщения: 106
Зарегистрирован: 16 дек 2018, 16:35
Имя: Антон
Благодарил (а): 5 раз
Поблагодарили: 4 раза

S7-300, запись размера блока данных

Сообщение tonyk »

Если в FB как параметр передаётся DB (не его номер!), то как записывать обращения к данным внутри этого DB? Ткните пальцем в примеры, пожалуйста.
У вас нет необходимых прав для просмотра вложений в этом сообщении.

AppCreator
здесь недавно
здесь недавно
Сообщения: 35
Зарегистрирован: 02 фев 2023, 10:38
Имя: Владимир
Страна: РФ
город/регион: Восьмипалатинск
Благодарил (а): 4 раза
Поблагодарили: 12 раз

S7-300, запись размера блока данных

Сообщение AppCreator »

Либо как пример ниже, либо нужно более четко описать задачу

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

respondent.DBX0.0 //bit 0 с адреса 0
respondent.DBB0 //byte с адреса 0
respondent.DBW0 //word с адреса 0
respondent.DBD0 //dword с адреса 0

Автор темы
tonyk
осмотрелся
осмотрелся
Сообщения: 106
Зарегистрирован: 16 дек 2018, 16:35
Имя: Антон
Благодарил (а): 5 раз
Поблагодарили: 4 раза

S7-300, запись размера блока данных

Сообщение tonyk »

AppCreator писал(а): 03 фев 2023, 10:46 Либо как пример ниже
Только что нашёл ответ на буржуйском форуме.
http://www.plctalk.com/qanda/showthread.php?p=432402
Ответить

Вернуться в «Simatic Step7»