- Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
- Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
- Не надо писать свой вопрос в первую попавшуюся тему - всегда лучше создать новую тему.
- За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения. Непонятно? - Читать здесь.
- Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
- Перед тем как что-то написать - читать здесь, а затем здесь и здесь.
- Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.
косвенная адресация DB S7-1200
Модератор: Глоб.модераторы
-
- здесь недавно
- Сообщения: 92
- Зарегистрирован: 09 июн 2017, 09:03
- Имя: Андрей А.
- Благодарил (а): 5 раз
- Поблагодарили: 8 раз
косвенная адресация DB S7-1200
Коллеги, приветствую. Появилась задача на вход блока Modbus Master подключить указатель на блок DB. Задача в том, что указатель должен смещаться в блоке на определенное количество байт, смещение прописывается в массиве и его значение должно суммироваться с указателем.
Указатель имеет вид P#DB7.DBX0.0 WORD 5. Как сюда прибавить содержимое массива?
Указатель имеет вид P#DB7.DBX0.0 WORD 5. Как сюда прибавить содержимое массива?
-
- эксперт
- Сообщения: 1035
- Зарегистрирован: 31 мар 2018, 12:05
- Имя: Вячеслав
- Благодарил (а): 100 раз
- Поблагодарили: 141 раз
косвенная адресация DB S7-1200
Опа, интересно))
Я пока не представляю как, и даже сомневаюсь, что вообще возможно
Отправлено спустя 2 минуты 17 секунд:
Тут надо Бергера поковырять...
Сам поинтер, что за тип? Эни?.. Максимум возможного пока вижу в секвенсере каком то. То есть предустановленные значения, которые меняются. Но и то... Очень навряд ли.
Любопытная тема ;)
Коллеги?
Отправлено спустя 1 минуту 53 секунды:
Ответ навскидку - нужное кол-во мастер блоков. Со своими поинтерами. Ну а уж вызывать их по условию - не проблема.
Я пока не представляю как, и даже сомневаюсь, что вообще возможно
Отправлено спустя 2 минуты 17 секунд:
Тут надо Бергера поковырять...
Сам поинтер, что за тип? Эни?.. Максимум возможного пока вижу в секвенсере каком то. То есть предустановленные значения, которые меняются. Но и то... Очень навряд ли.
Любопытная тема ;)
Коллеги?
Отправлено спустя 1 минуту 53 секунды:
Ответ навскидку - нужное кол-во мастер блоков. Со своими поинтерами. Ну а уж вызывать их по условию - не проблема.
-
- авторитет
- Сообщения: 865
- Зарегистрирован: 16 ноя 2016, 11:33
- Имя: Максим Владимирович
- Страна: Россия
- город/регион: Магнитогорск
- Благодарил (а): 16 раз
- Поблагодарили: 223 раза
косвенная адресация DB S7-1200
Если я направление мысли автора понял правильно, то обычно в таких ситуациях делают как-то так:
Вообще, как я понимаю, такое можно сделать, но это надо либо хорошо знать тонкости работы с SCL (как минимум в полном объёме руководства по программированию), либо посидеть с бубном и почитать темы про косвенную адресацию на SIOS / других форумах и примеры от Siemens типа этого:
https://support.industry.siemens.com/cs ... 0&lc=en-US
или делают большой NW/несколько NW в стиле: CMP== (какое-то выделенное значение из массива сравнивают с тем, что ждут) с последующим перемещением через MOVE в промежуточный буфер/структуру того, что должно переписываться/приниматься/отправляться в этом случае и в конце функции уже из этого промежуточного блока данные отправляют куда надо.
Вообще, как я понимаю, такое можно сделать, но это надо либо хорошо знать тонкости работы с SCL (как минимум в полном объёме руководства по программированию), либо посидеть с бубном и почитать темы про косвенную адресацию на SIOS / других форумах и примеры от Siemens типа этого:
https://support.industry.siemens.com/cs ... 0&lc=en-US
-
- эксперт
- Сообщения: 1035
- Зарегистрирован: 31 мар 2018, 12:05
- Имя: Вячеслав
- Благодарил (а): 100 раз
- Поблагодарили: 141 раз
косвенная адресация DB S7-1200
Скорее STL.
Однако речь только о внутризонных указателях.Операции сложения с содержимым указателей
Инструкции +AR1 P#y.x и +AR2 P#y.x прибавляют указатель к
содержимому указанного адресного регистра AR1 или AR2.
Видимо потому, что:
То есть как хранить 32 бита, еще, возможно, понятно ))Система STEP 7 различает три типа указателей:
• указатели на область (area pointers)
длина такого указателя составляет 32 бита и содержит определенный
адрес;
• указатели на DB (DB pointers)
длина такого указателя составляет 48 битов и содержит кроме адреса
(как в указателе на область) номер блока данных;
• ANY-указатели (ANY pointers)
длина такого указателя составляет 80 битов и содержит кроме
информации, общей с указателем на DB, например, тип данных
операнда.
Можно и так поизвращаться
Поскольку структура известна, то можно менять значения/назначения. Но опять же
Это межзонный указатель... И как хранить 48 бит, я не знаю.
Резюмируя - все таки набор блоков мастер, каждый со своим поинтером кажется мне оптимальным решением. Как минимум - понятным идущему по Вашим следам ;)
Отправлено спустя 6 минут 14 секунд:
PS Чуть побольше почитал, чуть повнимательнее посмотрел на картинку... Возможно я где то ошибся. Тема с Pointer и Any в Simatic, достаточно скользкая )) На мой взгляд, конечно. Этот постскриптум для того, кто знает чуть больше меня о этой теме, и захочет разнести меня тут в пух и прах ;)
-
- здесь недавно
- Сообщения: 94
- Зарегистрирован: 29 окт 2017, 19:52
- Имя: Дмитрий
- Благодарил (а): 5 раз
- Поблагодарили: 18 раз
косвенная адресация DB S7-1200
Доброе утро. Не понял автора, что необходимо сделать?
P#DB7.DBX0.0 WORD 5 это означает, что берется информация с 5 слов начиная от DB7.DBW0 по DB7.DBW4.
.
P#DB7.DBX0.0 WORD 5 это означает, что берется информация с 5 слов начиная от DB7.DBW0 по DB7.DBW4.
-
- освоился
- Сообщения: 271
- Зарегистрирован: 25 ноя 2018, 17:55
- Имя: Роман
- Благодарил (а): 4 раза
- Поблагодарили: 42 раза
косвенная адресация DB S7-1200
Автор,вы бы описали для чего вам сие действо, тогда, возможно, и решение станет более очевидным.
Случается нередко нам
И труд и мудрость видеть там,
Где стоит только догадаться
За дело просто взяться.
И труд и мудрость видеть там,
Где стоит только догадаться
За дело просто взяться.
-
- авторитет
- Сообщения: 865
- Зарегистрирован: 16 ноя 2016, 11:33
- Имя: Максим Владимирович
- Страна: Россия
- город/регион: Магнитогорск
- Благодарил (а): 16 раз
- Поблагодарили: 223 раза
косвенная адресация DB S7-1200
Есть один нюанс: в S7-1200 нет STL, только SCL...
Да там всë можно сделать простым выбором из множества сравнений через CMP==, большинство людей так бы и делало.
-
- здесь недавно
- Сообщения: 92
- Зарегистрирован: 09 июн 2017, 09:03
- Имя: Андрей А.
- Благодарил (а): 5 раз
- Поблагодарили: 8 раз
косвенная адресация DB S7-1200
Приветствую всех и спасибо за ответы. Мне нужно считывать регистры modbus rtu устройства. Проблема в том, что производитель так хитро фильтрует запросы, что нужно точно указывать размер считываемого параметра. Параметры от 1 до 4-х регистров. Считывание оптом не проходит, нужно именно поочередное считывание каждого параметра, по одному в каждом запросе, иначе возникает ошибка с кодом 83 "Illegal address". Хотел создать несколько массивов с адресами регистров слейва, смещением от начала блока данных и количеством слов считываемого параметра, подавать на вход блока Modbus_master и считывать по очереди в один блок данных.
-
- эксперт
- Сообщения: 1035
- Зарегистрирован: 31 мар 2018, 12:05
- Имя: Вячеслав
- Благодарил (а): 100 раз
- Поблагодарили: 141 раз
косвенная адресация DB S7-1200
Печаль)) Не знал. Познавая глубину кастрированности 1200,думаю перебор мастер блоков, и вовсе единственный вариант ;)
-
- авторитет
- Сообщения: 865
- Зарегистрирован: 16 ноя 2016, 11:33
- Имя: Максим Владимирович
- Страна: Россия
- город/регион: Магнитогорск
- Благодарил (а): 16 раз
- Поблагодарили: 223 раза
косвенная адресация DB S7-1200
Надо опыты ставить на реальном железе.
Там какой блок испольуется? Modbus_Master?
Попробуйте на горячую изменять ему значения DATA_ADDR, DATA_LEN, DATA_PTR, блок вообще это нормально будет воспринимать или нет.
Или несколько вызовов этого блока сделать с разными параметрами, главное чтобы одновременно они не выполнялись.
Siemens (и здесь S7-1200 не исключение, а скорее яркий тому пример) ведь создан сумрачным германским гением, здесь всё должно быть чётко и понятно, безо всяких финтифлюшек )
Там какой блок испольуется? Modbus_Master?
Попробуйте на горячую изменять ему значения DATA_ADDR, DATA_LEN, DATA_PTR, блок вообще это нормально будет воспринимать или нет.
Или несколько вызовов этого блока сделать с разными параметрами, главное чтобы одновременно они не выполнялись.
Siemens (и здесь S7-1200 не исключение, а скорее яркий тому пример) ведь создан сумрачным германским гением, здесь всё должно быть чётко и понятно, безо всяких финтифлюшек )
-
- эксперт
- Сообщения: 1035
- Зарегистрирован: 31 мар 2018, 12:05
- Имя: Вячеслав
- Благодарил (а): 100 раз
- Поблагодарили: 141 раз
косвенная адресация DB S7-1200
Вот и интересно - как это сделать. Вопрос, как я понимаю, в этом. Как эти константы в виде Pointer подавать в виде переменных.Parliament74 писал(а): ↑13 дек 2022, 20:15 Попробуйте на горячую изменять ему значения DATA_ADDR, DATA_LEN, DATA_PTR
Ну а то, что блоки (несколько штук, с разными этими поинтер, пусть и по одному адресу) будут работать, будучи, конечно, засинхронизированными - тут, у меня сомнений нет.
-
- здесь недавно
- Сообщения: 94
- Зарегистрирован: 29 окт 2017, 19:52
- Имя: Дмитрий
- Благодарил (а): 5 раз
- Поблагодарили: 18 раз
косвенная адресация DB S7-1200
В 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 //куда передаем данные
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 //куда передаем данные
-
- освоился
- Сообщения: 271
- Зарегистрирован: 25 ноя 2018, 17:55
- Имя: Роман
- Благодарил (а): 4 раза
- Поблагодарили: 42 раза
косвенная адресация DB S7-1200
Я,честно признаться, так и не понял, чем задача автора принципиально отличается от задачи опроса нескольких слейвов (в данном случае меняем не адрес слейва, а начальный адрес, читаем в буфер, из буфера раздаем кому положено).Или автор решил как то половчее это сделать?
Случается нередко нам
И труд и мудрость видеть там,
Где стоит только догадаться
За дело просто взяться.
И труд и мудрость видеть там,
Где стоит только догадаться
За дело просто взяться.
-
- эксперт
- Сообщения: 1035
- Зарегистрирован: 31 мар 2018, 12:05
- Имя: Вячеслав
- Благодарил (а): 100 раз
- Поблагодарили: 141 раз
косвенная адресация DB S7-1200
Если бы была возможность представлять эти Pointer как переменные, а не как константы, то и блок был бы в коде один.
Вроде как объект... ООП...
Но гарантия, что следующий программист бы голову поломал - чего тут происходит ;)
-
- здесь недавно
- Сообщения: 92
- Зарегистрирован: 09 июн 2017, 09:03
- Имя: Андрей А.
- Благодарил (а): 5 раз
- Поблагодарили: 8 раз
косвенная адресация DB S7-1200
Так и начал делать. В этот раз всего 16 параметров, не критично. Но нужно будет поэкспериментировать с указателями, пригодится.
-
- здесь недавно
- Сообщения: 94
- Зарегистрирован: 29 окт 2017, 19:52
- Имя: Дмитрий
- Благодарил (а): 5 раз
- Поблагодарили: 18 раз
косвенная адресация DB S7-1200
А причем тут указатель, если надо считывать регистры? Я делал программу когда с одним функциональным блоком опрашивал и DI, AI, HR и управлял DO. Все работает, но через определенное время и сам забываешь, что за "код" там смастерил.
-
- эксперт
- Сообщения: 1035
- Зарегистрирован: 31 мар 2018, 12:05
- Имя: Вячеслав
- Благодарил (а): 100 раз
- Поблагодарили: 141 раз
косвенная адресация DB S7-1200
Потому что это обязательный In блока (FB он там или SFB, не суть)
Либо у Вас указатели были одинаковыми, либо расскажите, как Вы их каждый раз меняли ;)Dmitriy1983 писал(а): ↑14 дек 2022, 07:29 Я делал программу когда с одним функциональным блоком опрашивал и DI, AI, HR и управлял DO
Отправлено спустя 8 минут 55 секунд:
PS Тут же еще вот в чем проблема:
Казалось бы, ну указатель, ну и пусть указывает на какую то область (DB), а в самом DB будем менять данные. Однако эта область, если мне память не изменяет, должна иметь жесткую структуру. Хотя... Указателей 2. Две структуры. Единственное - область данных нужно максимальную задать. То есть в этой структуре - там же и адрес, номер ф-ции и т.д. И - кол во байтов (регистров). Может так получится...
Но тут надо хотя бы в симуляторе, с TCP поиграть. А это Advanced Simulator и значит 1500 ))
a93911, попробуйте в эту сторону подумать.
-
- здесь недавно
- Сообщения: 94
- Зарегистрирован: 29 окт 2017, 19:52
- Имя: Дмитрий
- Благодарил (а): 5 раз
- Поблагодарили: 18 раз
косвенная адресация DB S7-1200
Если мы говорим про FB Modbas_Master, то там нет такого обязательного IN. Во входа заходят только цифры (MB адрес, режим, начальный регистр и длина). А вот на выход можно и указатель закинуть или просто массив.
Отправлено спустя 1 минуту 13 секунд:
Имею ввиду IN никак не указатель.
Отправлено спустя 1 минуту 13 секунд:
Имею ввиду IN никак не указатель.
-
- эксперт
- Сообщения: 1035
- Зарегистрирован: 31 мар 2018, 12:05
- Имя: Вячеслав
- Благодарил (а): 100 раз
- Поблагодарили: 141 раз
косвенная адресация DB S7-1200
Dmitriy1983, возможно речь о разных блоках/версиях. И IN возможно по факту - INOUT.
По крайней мере, я не практикую новые линейки вообще. От любопытства ради ковырял, как раз на предмет обмена по Modbus на симуляторах
И поинтер тут обязательная составляющая. Не думаю, что RTU кардинально отличается
По крайней мере, я не практикую новые линейки вообще. От любопытства ради ковырял, как раз на предмет обмена по Modbus на симуляторах
И поинтер тут обязательная составляющая. Не думаю, что RTU кардинально отличается
-
- эксперт
- Сообщения: 1172
- Зарегистрирован: 14 ноя 2013, 20:35
- Имя: Анатолий Сергеевич
- Страна: Россия
- город/регион: Башкортостан
- Благодарил (а): 13 раз
- Поблагодарили: 68 раз
косвенная адресация DB S7-1200
Я организовывал опрос по рту ячейки сепамовские года 4 назад, вроде работает...
- [+] Опрос Перебираются адреса устройств для опроса, запись ведется в один и тот же массив DataPTR
- [+] Рукописный блок В данном блоке перебираются адреса устройств - по завершению опроса одного устройства опрос переходит к следующему и т.д.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
-
- здесь недавно
- Сообщения: 94
- Зарегистрирован: 29 окт 2017, 19:52
- Имя: Дмитрий
- Благодарил (а): 5 раз
- Поблагодарили: 18 раз
косвенная адресация DB S7-1200
Вот и я на подобие делал, только у меня много всяких регистров надо было 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;
//Настройка параметров
#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;
-
- здесь недавно
- Сообщения: 92
- Зарегистрирован: 09 июн 2017, 09:03
- Имя: Андрей А.
- Благодарил (а): 5 раз
- Поблагодарили: 8 раз
косвенная адресация DB S7-1200
Как я уже писал, производитель устройства не позволяет считывать "оптом", нужно читать по 1 параметру за каждый запрос. И размер параметров разный, от 1 до 4 регистров.Dmitriy1983 писал(а): ↑14 дек 2022, 07:29 А причем тут указатель, если надо считывать регистры? Я делал программу когда с одним функциональным блоком опрашивал и DI, AI, HR и управлял DO. Все работает, но через определенное время и сам забываешь, что за "код" там смастерил.
-
- здесь недавно
- Сообщения: 94
- Зарегистрирован: 29 окт 2017, 19:52
- Имя: Дмитрий
- Благодарил (а): 5 раз
- Поблагодарили: 18 раз
косвенная адресация DB S7-1200
Вы указатель то, на что хотите повесить? Причем тут очередность? Если у Вас разные входные параметры, то не надо туда указатель.
-
- здесь недавно
- Сообщения: 92
- Зарегистрирован: 09 июн 2017, 09:03
- Имя: Андрей А.
- Благодарил (а): 5 раз
- Поблагодарили: 8 раз
косвенная адресация DB S7-1200
Да, здесь скорее всего тип Variant подойдет лучше всего, а потом конвертировать в нужныйstesl писал(а): ↑14 дек 2022, 08:16 Казалось бы, ну указатель, ну и пусть указывает на какую то область (DB), а в самом DB будем менять данные. Однако эта область, если мне память не изменяет, должна иметь жесткую структуру. Хотя... Указателей 2. Две структуры. Единственное - область данных нужно максимальную задать. То есть в этой структуре - там же и адрес, номер ф-ции и т.д. И - кол во байтов (регистров). Может так получится...
Но тут надо хотя бы в симуляторе, с TCP поиграть. А это Advanced Simulator и значит 1500 ))
a93911, попробуйте в эту сторону подумать.
Отправлено спустя 19 минут 31 секунду:
Спасибо. Думаю, самый оптимальный вариант будет таким: создаем массивы с адресами регистров слейва, размером читаемых данных. Делаем запрос, результат помещается в DB с одним параметром типа variant, далее пишем этот результат в массив variant и переходим к следующему запросу (цикл). Далее вручную преобразуем элементы массива variant в нужный тип данных.megavolt86 писал(а): ↑14 дек 2022, 11:13 Без поинтеров обошелся, хотя это делал давно, сайчас бы сделал по другому наверное...поизящнее