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

косвенная адресация DB S7-1200

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

Ответить

Автор темы
a93911
здесь недавно
здесь недавно
Сообщения: 92
Зарегистрирован: 09 июн 2017, 09:03
Имя: Андрей А.
Благодарил (а): 5 раз
Поблагодарили: 8 раз

косвенная адресация DB S7-1200

Сообщение a93911 »

Коллеги, приветствую. Появилась задача на вход блока Modbus Master подключить указатель на блок DB. Задача в том, что указатель должен смещаться в блоке на определенное количество байт, смещение прописывается в массиве и его значение должно суммироваться с указателем.

Указатель имеет вид P#DB7.DBX0.0 WORD 5. Как сюда прибавить содержимое массива?

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

косвенная адресация DB S7-1200

Сообщение stesl »

Опа, интересно))
Я пока не представляю как, и даже сомневаюсь, что вообще возможно

Отправлено спустя 2 минуты 17 секунд:
Тут надо Бергера поковырять...
Сам поинтер, что за тип? Эни?.. Максимум возможного пока вижу в секвенсере каком то. То есть предустановленные значения, которые меняются. Но и то... Очень навряд ли.
Любопытная тема ;)
Коллеги?

Отправлено спустя 1 минуту 53 секунды:
Ответ навскидку - нужное кол-во мастер блоков. Со своими поинтерами. Ну а уж вызывать их по условию - не проблема.

Parliament74
авторитет
авторитет
Сообщения: 865
Зарегистрирован: 16 ноя 2016, 11:33
Имя: Максим Владимирович
Страна: Россия
город/регион: Магнитогорск
Благодарил (а): 16 раз
Поблагодарили: 223 раза

косвенная адресация DB S7-1200

Сообщение Parliament74 »

Если я направление мысли автора понял правильно, то обычно в таких ситуациях делают как-то так:
stesl писал(а): 12 дек 2022, 16:09 Ответ навскидку - нужное кол-во мастер блоков. Со своими поинтерами. Ну а уж вызывать их по условию - не проблема.
или делают большой NW/несколько NW в стиле: CMP== (какое-то выделенное значение из массива сравнивают с тем, что ждут) с последующим перемещением через MOVE в промежуточный буфер/структуру того, что должно переписываться/приниматься/отправляться в этом случае и в конце функции уже из этого промежуточного блока данные отправляют куда надо.

Вообще, как я понимаю, такое можно сделать, но это надо либо хорошо знать тонкости работы с SCL (как минимум в полном объёме руководства по программированию), либо посидеть с бубном и почитать темы про косвенную адресацию на SIOS / других форумах и примеры от Siemens типа этого:
https://support.industry.siemens.com/cs ... 0&lc=en-US

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

косвенная адресация DB S7-1200

Сообщение stesl »

Parliament74 писал(а): 12 дек 2022, 20:11 хорошо знать тонкости работы с SCL
Скорее STL.
Операции сложения с содержимым указателей
Инструкции +AR1 P#y.x и +AR2 P#y.x прибавляют указатель к
содержимому указанного адресного регистра AR1 или AR2.
Однако речь только о внутризонных указателях.
Видимо потому, что:
Система STEP 7 различает три типа указателей:
• указатели на область (area pointers)
длина такого указателя составляет 32 бита и содержит определенный
адрес;
• указатели на DB (DB pointers)
длина такого указателя составляет 48 битов и содержит кроме адреса
(как в указателе на область) номер блока данных;
• ANY-указатели (ANY pointers)
длина такого указателя составляет 80 битов и содержит кроме
информации, общей с указателем на DB, например, тип данных
операнда.
То есть как хранить 32 бита, еще, возможно, понятно ))

Можно и так поизвращаться
Изображение

Поскольку структура известна, то можно менять значения/назначения. Но опять же
a93911 писал(а): 12 дек 2022, 12:19 P#DB7.DBX0.0 WORD 5
Это межзонный указатель... И как хранить 48 бит, я не знаю.

Резюмируя - все таки набор блоков мастер, каждый со своим поинтером кажется мне оптимальным решением. Как минимум - понятным идущему по Вашим следам ;)

Отправлено спустя 6 минут 14 секунд:
PS Чуть побольше почитал, чуть повнимательнее посмотрел на картинку... Возможно я где то ошибся. Тема с Pointer и Any в Simatic, достаточно скользкая )) На мой взгляд, конечно. Этот постскриптум для того, кто знает чуть больше меня о этой теме, и захочет разнести меня тут в пух и прах ;)

Dmitriy1983
здесь недавно
здесь недавно
Сообщения: 94
Зарегистрирован: 29 окт 2017, 19:52
Имя: Дмитрий
Благодарил (а): 5 раз
Поблагодарили: 18 раз

косвенная адресация DB S7-1200

Сообщение Dmitriy1983 »

Доброе утро. Не понял автора, что необходимо сделать?
a93911 писал(а): 12 дек 2022, 12:19 Задача в том, что указатель должен смещаться в блоке на определенное количество байт
.
P#DB7.DBX0.0 WORD 5 это означает, что берется информация с 5 слов начиная от DB7.DBW0 по DB7.DBW4.

Roman_33
освоился
освоился
Сообщения: 271
Зарегистрирован: 25 ноя 2018, 17:55
Имя: Роман
Благодарил (а): 4 раза
Поблагодарили: 42 раза

косвенная адресация DB S7-1200

Сообщение Roman_33 »

Автор,вы бы описали для чего вам сие действо, тогда, возможно, и решение станет более очевидным.
Случается нередко нам
И труд и мудрость видеть там,
Где стоит только догадаться
За дело просто взяться.

Parliament74
авторитет
авторитет
Сообщения: 865
Зарегистрирован: 16 ноя 2016, 11:33
Имя: Максим Владимирович
Страна: Россия
город/регион: Магнитогорск
Благодарил (а): 16 раз
Поблагодарили: 223 раза

косвенная адресация DB S7-1200

Сообщение Parliament74 »

Parliament74 писал(а): 12 дек 2022, 20:11 Скорее STL.
Есть один нюанс: в S7-1200 нет STL, только SCL...
Roman_33 писал(а): 13 дек 2022, 07:27 Автор,вы бы описали для чего вам сие действо, тогда, возможно, и решение станет более очевидным
Да там всë можно сделать простым выбором из множества сравнений через CMP==, большинство людей так бы и делало.

Автор темы
a93911
здесь недавно
здесь недавно
Сообщения: 92
Зарегистрирован: 09 июн 2017, 09:03
Имя: Андрей А.
Благодарил (а): 5 раз
Поблагодарили: 8 раз

косвенная адресация DB S7-1200

Сообщение a93911 »

Приветствую всех и спасибо за ответы. Мне нужно считывать регистры modbus rtu устройства. Проблема в том, что производитель так хитро фильтрует запросы, что нужно точно указывать размер считываемого параметра. Параметры от 1 до 4-х регистров. Считывание оптом не проходит, нужно именно поочередное считывание каждого параметра, по одному в каждом запросе, иначе возникает ошибка с кодом 83 "Illegal address". Хотел создать несколько массивов с адресами регистров слейва, смещением от начала блока данных и количеством слов считываемого параметра, подавать на вход блока Modbus_master и считывать по очереди в один блок данных.

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

косвенная адресация DB S7-1200

Сообщение stesl »

Parliament74 писал(а): 13 дек 2022, 12:01 Есть один нюанс: в S7-1200 нет STL, только SCL...
Печаль)) Не знал. Познавая глубину кастрированности 1200,думаю перебор мастер блоков, и вовсе единственный вариант ;)

Parliament74
авторитет
авторитет
Сообщения: 865
Зарегистрирован: 16 ноя 2016, 11:33
Имя: Максим Владимирович
Страна: Россия
город/регион: Магнитогорск
Благодарил (а): 16 раз
Поблагодарили: 223 раза

косвенная адресация DB S7-1200

Сообщение Parliament74 »

Надо опыты ставить на реальном железе.
Там какой блок испольуется? Modbus_Master?
Попробуйте на горячую изменять ему значения DATA_ADDR, DATA_LEN, DATA_PTR, блок вообще это нормально будет воспринимать или нет.
Или несколько вызовов этого блока сделать с разными параметрами, главное чтобы одновременно они не выполнялись.

Siemens (и здесь S7-1200 не исключение, а скорее яркий тому пример) ведь создан сумрачным германским гением, здесь всё должно быть чётко и понятно, безо всяких финтифлюшек )

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

косвенная адресация DB S7-1200

Сообщение stesl »

Parliament74 писал(а): 13 дек 2022, 20:15 Попробуйте на горячую изменять ему значения DATA_ADDR, DATA_LEN, DATA_PTR
Вот и интересно - как это сделать. Вопрос, как я понимаю, в этом. Как эти константы в виде Pointer подавать в виде переменных.
Ну а то, что блоки (несколько штук, с разными этими поинтер, пусть и по одному адресу) будут работать, будучи, конечно, засинхронизированными - тут, у меня сомнений нет.

Dmitriy1983
здесь недавно
здесь недавно
Сообщения: 94
Зарегистрирован: 29 окт 2017, 19:52
Имя: Дмитрий
Благодарил (а): 5 раз
Поблагодарили: 18 раз

косвенная адресация DB S7-1200

Сообщение Dmitriy1983 »

В RTU такого не дела, но в TCP IP работает. Думаю и здесь у тебя тоже должно работать. Вызывай блок по очередно с такимже экземпляром, но с разными DATA_ADDR и DATA_LEN, по выходу DONE от Modbus_Master. Ниже пример с S7conection на STL, но смысл тот же. На 1200 через "case" это можно сделать.

S001: CALL GET_S , "GET_SHUK"
REQ :="S7_con_Diagn".SHUDO_SHUK_Get.REQ
ID :=W#16#9
NDR :="S7_con_Diagn".SHUDO_SHUK_Get.Done
ERROR :="S7_con_Diagn".SHUDO_SHUK_Get.Error
STATUS :=#status
ADDR_1 :=P#DB108.DBX36.0 BYTE 4 //От куда читаем данные
RD_1 :=P#DB410.DBX0.0 BYTE 4 //куда передаем данные

A "S7_con_Diagn".SHUDO_SHUK_Get.Done
JCN end
L 2
T "In_from_SHUK".Step
JU end

S002: CALL GET_S , "GET_SHUK"
REQ :="S7_con_Diagn".SHUDO_SHUK_Get.REQ
ID :=W#16#9
NDR :="S7_con_Diagn".SHUDO_SHUK_Get.Done
ERROR :="S7_con_Diagn".SHUDO_SHUK_Get.Error
STATUS :=#status
ADDR_1 :=P#DB109.DBX36.0 BYTE 4 //От куда читаем данные
RD_1 :=P#DB410.DBX4.0 BYTE 4 //куда передаем данные

Roman_33
освоился
освоился
Сообщения: 271
Зарегистрирован: 25 ноя 2018, 17:55
Имя: Роман
Благодарил (а): 4 раза
Поблагодарили: 42 раза

косвенная адресация DB S7-1200

Сообщение Roman_33 »

Я,честно признаться, так и не понял, чем задача автора принципиально отличается от задачи опроса нескольких слейвов (в данном случае меняем не адрес слейва, а начальный адрес, читаем в буфер, из буфера раздаем кому положено).Или автор решил как то половчее это сделать?
Случается нередко нам
И труд и мудрость видеть там,
Где стоит только догадаться
За дело просто взяться.

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

косвенная адресация DB S7-1200

Сообщение stesl »

Roman_33 писал(а): 14 дек 2022, 06:55 Или автор решил как то половчее это сделать?
Если бы была возможность представлять эти Pointer как переменные, а не как константы, то и блок был бы в коде один.
Вроде как объект... ООП...
Но гарантия, что следующий программист бы голову поломал - чего тут происходит ;)

Автор темы
a93911
здесь недавно
здесь недавно
Сообщения: 92
Зарегистрирован: 09 июн 2017, 09:03
Имя: Андрей А.
Благодарил (а): 5 раз
Поблагодарили: 8 раз

косвенная адресация DB S7-1200

Сообщение a93911 »

stesl писал(а): 13 дек 2022, 17:09 Познавая глубину кастрированности 1200,думаю перебор мастер блоков, и вовсе единственный вариант ;)
Так и начал делать. В этот раз всего 16 параметров, не критично. Но нужно будет поэкспериментировать с указателями, пригодится.

Dmitriy1983
здесь недавно
здесь недавно
Сообщения: 94
Зарегистрирован: 29 окт 2017, 19:52
Имя: Дмитрий
Благодарил (а): 5 раз
Поблагодарили: 18 раз

косвенная адресация DB S7-1200

Сообщение Dmitriy1983 »

А причем тут указатель, если надо считывать регистры? Я делал программу когда с одним функциональным блоком опрашивал и DI, AI, HR и управлял DO. Все работает, но через определенное время и сам забываешь, что за "код" там смастерил.

Михайло
эксперт
эксперт
Сообщения: 3643
Зарегистрирован: 10 ноя 2009, 04:58
Имя: Толмачев Михаил Алексеевич
город/регион: г. Чехов, МО
Благодарил (а): 8 раз
Поблагодарили: 286 раз

косвенная адресация DB S7-1200

Сообщение Михайло »

Надо каждый раз подменять тип данных? Тогда наверное VARIANT.

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

косвенная адресация DB S7-1200

Сообщение stesl »

Dmitriy1983 писал(а): 14 дек 2022, 07:29 А причем тут указатель, если надо считывать регистры?
Потому что это обязательный In блока (FB он там или SFB, не суть)
Dmitriy1983 писал(а): 14 дек 2022, 07:29 Я делал программу когда с одним функциональным блоком опрашивал и DI, AI, HR и управлял DO
Либо у Вас указатели были одинаковыми, либо расскажите, как Вы их каждый раз меняли ;)

Отправлено спустя 8 минут 55 секунд:
PS Тут же еще вот в чем проблема:
Казалось бы, ну указатель, ну и пусть указывает на какую то область (DB), а в самом DB будем менять данные. Однако эта область, если мне память не изменяет, должна иметь жесткую структуру. Хотя... Указателей 2. Две структуры. Единственное - область данных нужно максимальную задать. То есть в этой структуре - там же и адрес, номер ф-ции и т.д. И - кол во байтов (регистров). Может так получится...
Но тут надо хотя бы в симуляторе, с TCP поиграть. А это Advanced Simulator и значит 1500 ))
a93911, попробуйте в эту сторону подумать.

Dmitriy1983
здесь недавно
здесь недавно
Сообщения: 94
Зарегистрирован: 29 окт 2017, 19:52
Имя: Дмитрий
Благодарил (а): 5 раз
Поблагодарили: 18 раз

косвенная адресация DB S7-1200

Сообщение Dmitriy1983 »

Если мы говорим про FB Modbas_Master, то там нет такого обязательного IN. Во входа заходят только цифры (MB адрес, режим, начальный регистр и длина). А вот на выход можно и указатель закинуть или просто массив.

Отправлено спустя 1 минуту 13 секунд:
Имею ввиду IN никак не указатель.

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

косвенная адресация DB S7-1200

Сообщение stesl »

Dmitriy1983, возможно речь о разных блоках/версиях. И IN возможно по факту - INOUT.
По крайней мере, я не практикую новые линейки вообще. От любопытства ради ковырял, как раз на предмет обмена по Modbus на симуляторах


И поинтер тут обязательная составляющая. Не думаю, что RTU кардинально отличается
Аватара пользователя

megavolt86
эксперт
эксперт
Сообщения: 1172
Зарегистрирован: 14 ноя 2013, 20:35
Имя: Анатолий Сергеевич
Страна: Россия
город/регион: Башкортостан
Благодарил (а): 13 раз
Поблагодарили: 68 раз

косвенная адресация DB S7-1200

Сообщение megavolt86 »

a93911 писал(а): 14 дек 2022, 07:07 В этот раз всего 16 параметров, не критично
Я организовывал опрос по рту ячейки сепамовские года 4 назад, вроде работает...
[+] Опрос
Блок опроса.png
Перебираются адреса устройств для опроса, запись ведется в один и тот же массив DataPTR
[+] Рукописный блок
Блок заполнения внешнего массива.png
Пременные в блок заполнения внешнего массива.png
В данном блоке перебираются адреса устройств - по завершению опроса одного устройства опрос переходит к следующему и т.д.
Так же по завершении опроса полученные данные записываются из DataPTR во внешнюю ДБ.

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

#FE_Busy(CLK := #Busy);
#FE_Error(CLK := #Error);
#RE_Error(CLK := #Error);
#RE_Done(CLK:=#Done);
//Формирование сигнала для запроса
IF #RE_Done.Q OR #FE_Error.Q OR "FirstScan" THEN
    #Req := 1;
ELSIF #Req THEN
    #Req := 0;
END_IF;
//Действие при ошибке
IF #RE_Error.Q THEN
    "MB_Units".Unit[#MB_Addr].Error := 1;//Запись ошибки в журнал
    FOR #i := 1 TO 3  BY 1 DO
        #Data_PTR[#i] := 0;//При ошибке принятые данные равны 0
    END_FOR;
    IF #i = 3 THEN
        #i := 1;
    END_IF;
ELSE
    IF #FE_Busy.Q THEN
        "MB_Units".Unit[#MB_Addr].Error := 0;
    END_IF;
END_IF;
//При удачном завершении обмена данные записываются во внешний ДБ
IF #FE_Busy.Q THEN
    "MB_Units".Unit[#MB_Addr].L := #Data_PTR;
    "UnCur"(Unit := #Data_PTR,
            Error := "MB_Units".Unit[#MB_Addr].Error,
            Imbalance := 50.0,
            Cur => "MB_Units".Unit[#MB_Addr].Cur,
            Status => "MB_Units".Unit[#MB_Addr].Status);
END_IF;
//При удачном завершении обмена опрос переходит к следующему устройству
IF #FE_Busy.Q OR #RE_Error.Q THEN
    IF #MB_Addr >= 1 AND #MB_Addr <= 11 THEN
        (*Ячейки 2,5,7,8,11 исключить из опроса, видимо сепамы настроены нестандартно*)
        IF #MB_Addr = 1 OR #MB_Addr = 4 OR #MB_Addr = 10 THEN
            #MB_Addr := #MB_Addr + 2;
        ELSIF #MB_Addr = 6 THEN
            #MB_Addr := #MB_Addr + 3;
        ELSE
            #MB_Addr := #MB_Addr + 1;
        END_IF;
    ELSE
        #MB_Addr := 1;
    END_IF;
END_IF;
Без поинтеров обошелся, хотя это делал давно, сайчас бы сделал по другому наверное...поизящнее
У вас нет необходимых прав для просмотра вложений в этом сообщении.
:ext_secret:

Dmitriy1983
здесь недавно
здесь недавно
Сообщения: 94
Зарегистрирован: 29 окт 2017, 19:52
Имя: Дмитрий
Благодарил (а): 5 раз
Поблагодарили: 18 раз

косвенная адресация DB S7-1200

Сообщение Dmitriy1983 »

Вот и я на подобие делал, только у меня много всяких регистров надо было cчитывать и записывать, но в modbusTCPIP.
//Настройка параметров
#Setup.InterfaceId := 64;
#Setup.ID := #Seting.#ID;
#Setup.ConnectionType := 11;
#Setup.ActiveEstablished := true;
#Setup.RemoteAddress.ADDR[1] := #Seting.#IPv4_adress[1];
#Setup.RemoteAddress.ADDR[2] := #Seting.#IPv4_adress[2];
#Setup.RemoteAddress.ADDR[3] := #Seting.#IPv4_adress[3];
#Setup.RemoteAddress.ADDR[4] := #Seting.#IPv4_adress[4];
#Setup.RemotePort := 502;

#Setup.LocalPort := 0;
#Client.MB_Unit_ID := #Seting.#MB_Adress;

#V1 := (#Max_RegQBool / 16) + 1;
#V2 := (#Max_RegInBool / 16) + 1;

//Сброс ненужноых регистров
//FOR #i := #V1+1 TO 100 DO //Сбрасываем все выхода в 0
// #Master_RegQBool[#i] := 0;
//END_FOR;
FOR #i := #V2 + 1 TO 100 DO //Сбрасываем все выхода в 0
#Master_RegInBool[#i] := 0;
END_FOR;
FOR #i := #Max_RegInWord + 1 TO 100 DO //Сбрасываем AI-1 в 0
#Master_RegInWord[#i] := 0;
END_FOR;
FOR #i := #Max_RegInWord2 + 1 TO 100 DO //Сбрасываем AI-2 в 0
#Master_RegInWord2[#i] := 0;
END_FOR;
FOR #i := #Max_RegHR + 1 TO 100 DO //Сбрасываем HR в 0
#Master_RegHR[#i] := 0;
END_FOR;

//Копирование максимально возможных регистров со смещением, если регистров больше 0

IF #Max_RegInBool > 0 THEN
#Slave_RegInBool := #RegInBool + 10000;
END_IF;
IF #Max_RegQBool > 0 THEN
#Slave_RegQBool := #RegQBool + 0;
END_IF;
IF #Max_RegInWord > 0 THEN
#Slave_RegInWord := #RegInWord + 30000;
END_IF;
IF #Max_RegInWord2 > 0 THEN
#Slave_RegInWord2 := #RegInWord2 + 30000;
END_IF;
IF #Max_RegInWord3 > 0 THEN
#Slave_RegInWord3 := #RegInWord3 + 30000;
END_IF;
IF #Max_RegHR > 0 THEN
#Slave_RegHR := #RegHR + 40000;
END_IF;


//При первом пуске
IF ("FirstScan" OR #DISCONNECT) THEN
#Step := 1;
#Addr := #Slave_RegInBool;
#Mode := 0;
//Sorokin 17/11
#SBHR := #SB := false;
END_IF;


#FP(CLK := #SB); // Обработка по + фронту нажатия на кнопку записи DQ
#NP(CLK := #SB );// Обработка по - фронту нажатия на кнопку записи DQ


IF (#NP.Q) THEN
#Write1 := false; // Сбросить обработку при нажатии кнопок упавления
#Write2 := true; // Активировать пост обработку после отжатия кнопок упавления
END_IF;

IF (#FP.Q) THEN
//Сброс ненужной информации из буфера
FOR #i := 1 TO 100 DO
#Information[#i] := 0;
END_FOR;

#Write1 := true; // Активировать обработку при нажатии кнопок упавления
#Write2 := false;// Сбросить пост обработку после отжатия кнопок упавления
#Step := 0;//Шаг записи дискретных выходов
END_IF;


CASE #Step OF
0:// Запись дискретных выходов
IF (#Write1 AND #Client.DONE AND #Client.STATUS=0) THEN

FOR #i := 1 TO #V1 DO// Записываем данные DQ
#Information[#i] := #Master_RegQBool[#i];
END_FOR;

#Addr := #Slave_RegQBool;//Начальный адрес записи
#Mode := 1;
#Lengs := INT_TO_UINT(#Max_RegQBool);//Длина регистра
ELSIF (#Write2 AND #Client.DONE AND #Client.STATUS=0) THEN

FOR #i := 1 TO #V1 DO// Записываем данные DQ
#Information[#i] := #Master_RegQBool[#i];
END_FOR;

#Addr := #Slave_RegQBool;//Начальный адрес записи
#Mode := 1;
#Lengs := INT_TO_UINT(#Max_RegQBool);//Длина регистра
#TR := #TR + 1;

IF (#TR >= 3) THEN
#Write1 := FALSE;
#Write2 := false;
#TR := 0;
#Addr := #Slave_RegInBool;//Начальный адрес чтения
#Mode := 0;//Чтение DI
#Step := 1;//Шаг Чтение DI
#Lengs := INT_TO_UINT(#Max_RegInBool);//Длина регистра
END_IF;

END_IF;

1: //Чтение дискретных входoв
IF (#Client.DONE) THEN

FOR #i := 1 TO #V2 DO //Считывание информации о DI
#Master_RegInBool[#i] := #Information[#i];
END_FOR;

//Сброс ненужной информации из буфера
FOR #i := 1 TO 100 DO
#Information[#i] := 0;
END_FOR;

#Addr := #Slave_RegInWord;
#Mode := 0;
#Step := 2;//Шаг Чтение AI
#Lengs := INT_TO_UINT(#Max_RegInWord);//Длина регистра
END_IF;

2: //Чтение аналоговых входoв 1
IF (#Client.DONE ) THEN

FOR #i := 1 TO #Max_RegInWord DO //Считывание информации о AI
#Master_RegInWord[#i] := #Information[#i];
END_FOR;

//Сброс ненужной информации из буфера
FOR #i := 1 TO 100 DO
#Information[#i] := 0;
END_FOR;

#Addr := #Slave_RegInWord2;
#Mode := 0;
#Step := 3;//Шаг Чтение AI 2
#Lengs := INT_TO_UINT(#Max_RegInWord2);//Длина регистра
END_IF;

3: //Чтение аналоговых входoв 2
IF (#Client.DONE) THEN

FOR #i := 1 TO #Max_RegInWord2 DO //Считывание информации о AI 2
#Master_RegInWord2[#i] := #Information[#i];
END_FOR;

//Сброс ненужной информации из буфера
FOR #i := 1 TO 100 DO
#Information[#i] := 0;
END_FOR;

#Addr := #Slave_RegInWord3;
#Mode := 0;
#Step := 4;//Шаг Чтение AI 3
#Lengs := INT_TO_UINT(#Max_RegInWord3);//Длина регистра
END_IF;

4: //Чтение аналоговых входoв 3
IF (#Client.DONE) THEN

FOR #i := 1 TO #Max_RegInWord3 DO //Считывание информации о AI 3
#Master_RegInWord3[#i] := #Information[#i];
END_FOR;

//Сброс ненужной информации из буфера
FOR #i := 1 TO 100 DO
#Information[#i] := 0;
END_FOR;

IF (#SBHR) THEN //Если включен режим записи холдинг регистров
FOR #i := 1 TO #Max_RegHR DO// Записываем данные HR
#Information[#i] := #Master_RegHR[#i];
END_FOR;
#SBHR := false; //Сброс кнопки активации изменения HR
#Addr := #Slave_RegHR;
#Mode := 1;
#Step := 5;//Шаг Чтение HR
#Lengs := INT_TO_UINT(#Max_RegHR);//Длина регистра
ELSE //Если не включен режим записи холдинг регистров - переход на чтение DI
#Addr := #Slave_RegInBool;
#Mode := 0;
#Step := 1;//Шаг Чтение DI
#Lengs := INT_TO_UINT(#Max_RegInBool);//Длина регистра
END_IF;
END_IF;


5: //Переходный процесс на чтение DI при записи холдинг регистров
IF (#Client.DONE AND NOT #SBHR) THEN
FOR #i := 1 TO 100 DO //Сброс ненужной информации из буфера
#Information[#i] := 0;
END_FOR;
#Addr := #Slave_RegInBool;
#Mode := 0;
#Step := 1;//Шаг Чтение DI
#Lengs := INT_TO_UINT(#Max_RegInBool);//Длина регистра
///sorokin 17/11
#SBHR := false;
END_IF;
END_CASE;


#Client(REQ :=NOT (#Client.BUSY AND #Client.DISCONNECT),
DISCONNECT := #DISCONNECT ,
MB_MODE := #Mode,
MB_DATA_ADDR := #Addr,
MB_DATA_LEN := #Lengs,
MB_DATA_PTR :=#Information,
CONNECT := #Setup);
//Если в течение указанного времени нет удачной операции, появляется ошибка соединения
#Timer_On(IN := NOT #Client.DONE,
PT := T#5s,
Q => #Er_con);




#Status := #Client.STATUS;

Автор темы
a93911
здесь недавно
здесь недавно
Сообщения: 92
Зарегистрирован: 09 июн 2017, 09:03
Имя: Андрей А.
Благодарил (а): 5 раз
Поблагодарили: 8 раз

косвенная адресация DB S7-1200

Сообщение a93911 »

Dmitriy1983 писал(а): 14 дек 2022, 07:29 А причем тут указатель, если надо считывать регистры? Я делал программу когда с одним функциональным блоком опрашивал и DI, AI, HR и управлял DO. Все работает, но через определенное время и сам забываешь, что за "код" там смастерил.
Как я уже писал, производитель устройства не позволяет считывать "оптом", нужно читать по 1 параметру за каждый запрос. И размер параметров разный, от 1 до 4 регистров.

Dmitriy1983
здесь недавно
здесь недавно
Сообщения: 94
Зарегистрирован: 29 окт 2017, 19:52
Имя: Дмитрий
Благодарил (а): 5 раз
Поблагодарили: 18 раз

косвенная адресация DB S7-1200

Сообщение Dmitriy1983 »

Вы указатель то, на что хотите повесить? Причем тут очередность? Если у Вас разные входные параметры, то не надо туда указатель.

Автор темы
a93911
здесь недавно
здесь недавно
Сообщения: 92
Зарегистрирован: 09 июн 2017, 09:03
Имя: Андрей А.
Благодарил (а): 5 раз
Поблагодарили: 8 раз

косвенная адресация DB S7-1200

Сообщение a93911 »

stesl писал(а): 14 дек 2022, 08:16 Казалось бы, ну указатель, ну и пусть указывает на какую то область (DB), а в самом DB будем менять данные. Однако эта область, если мне память не изменяет, должна иметь жесткую структуру. Хотя... Указателей 2. Две структуры. Единственное - область данных нужно максимальную задать. То есть в этой структуре - там же и адрес, номер ф-ции и т.д. И - кол во байтов (регистров). Может так получится...
Но тут надо хотя бы в симуляторе, с TCP поиграть. А это Advanced Simulator и значит 1500 ))
a93911, попробуйте в эту сторону подумать.
Да, здесь скорее всего тип Variant подойдет лучше всего, а потом конвертировать в нужный

Отправлено спустя 19 минут 31 секунду:
megavolt86 писал(а): 14 дек 2022, 11:13 Без поинтеров обошелся, хотя это делал давно, сайчас бы сделал по другому наверное...поизящнее
Спасибо. Думаю, самый оптимальный вариант будет таким: создаем массивы с адресами регистров слейва, размером читаемых данных. Делаем запрос, результат помещается в DB с одним параметром типа variant, далее пишем этот результат в массив variant и переходим к следующему запросу (цикл). Далее вручную преобразуем элементы массива variant в нужный тип данных.
Ответить

Вернуться в «Общие вопросы»