Просмотр полной версии : Помогите с синтаксисом ST!
ANDREY2002
26.09.2012, 01:32
есть 5 входных переменных типа BOOL и массив
можно ли каким либо образом обращаться к входным переменным в теле цикла как например к массиву
VAR
arr: ARRAY [1..5] OF BYTE; (*êîä îøèáêè*)
x: INT;
END_VAR
VAR_INPUT
in1: BOOL;
in2: BOOL;
in3: BOOL;
in4: BOOL;
in5: BOOL;
END_VAR
FOR x:=1 TO 5 DO
IF in(x)=TRUE THEN ?????????
arr[x]:=3; END_IF
END_FOR
Помогите кто знает! очень нужно!
VAR
in1, in2, in3, in4, in5: BOOL;
inp: POINTER TO BOOL;
x: INT;
END_VAR
FOR x := 0 TO 4 DO
inp := ADR(in1) + x;
IF inp^ THEN
(* Whatever *)
END_IF
END_FORТолько надо убедиться, что все переменные друг за другом в памяти идут и не попадают под выравнивание.
Вообще программисту, который пишет «IF что-то = TRUE THEN» вместо «IF что-то THEN», я настоятельно рекомендую не баловаться указателями и делать подобные вещи через промежуточный массив.
VAR
in1, in2, in3, in4, in5: BOOL;
inp: POINTER TO BOOL;
x: INT;
END_VAR
FOR x := 0 TO 4 DO
inp := ADR(in1) + x;
IF inp^ THEN
(* Whatever *)
END_IF
END_FORТолько надо убедиться, что все переменные друг за другом в памяти идут и не попадают под выравнивание.
Вообще программисту, который пишет «IF что-то = TRUE THEN» вместо «IF что-то THEN», я настоятельно рекомендую не баловаться указателями и делать подобные вещи через промежуточный массив.
A что, компилятор пропустил указатель на буль?
Почему он не должен был его пропустить?
должен был ругаться что с такими переменными работает инструкция BITADR, но это по памяти, может уже что поменялось
lara197a
26.09.2012, 09:30
Указатель работает только с WORD и DWORD(справка КДС)
А компилиться с бит то же будет
ANDREY2002
26.09.2012, 09:40
VAR
in1, in2, in3, in4, in5: BOOL;
inp: POINTER TO BOOL;
x: INT;
END_VAR
FOR x := 0 TO 4 DO
inp := ADR(in1) + x;
IF inp^ THEN
(* Whatever *)
END_IF
END_FORТолько надо убедиться, что все переменные друг за другом в памяти идут и не попадают под выравнивание.
Вообще программисту, который пишет «IF что-то = TRUE THEN» вместо «IF что-то THEN», я настоятельно рекомендую не баловаться указателями и делать подобные вещи через промежуточный массив.
спасибо, Yegor
насчет промежуточного массива не совсем понятно
ведь каждому члену массива нужно присвоить какой то вход( а если их 100) для каждого писать?
но ведь мне и надо автоматизировать этот процесс!
присвоив указателю этот же указатель плюс один получим второй байт переменной, так что нижняя точка это все же байт. И у меня КДС ругается, может дело в настройках среды или в версии
Дмитрий Артюховский
26.09.2012, 10:26
хулиганством занимаетесь ))
вспомните, что битовые переменные простенько так объединяются в BYTE или WORD....
считайте их одним байтом, а в цикле пробегите по нему битововй маской с AND для проверки установки отдельных битов, а еще выстрее сделайте CASE на интересующие комбинации битов
должен был ругаться что с такими переменными работает инструкция BITADRНе будет она с такими переменными работать. Даже не скомпилируется.
Указатель работает только с WORD и DWORD(справка КДС)
A pointer can point to any data type or function block even to user-defined types.
насчет промежуточного массива не совсем понятно
ведь каждому члену массива нужно присвоить какой то вход( а если их 100) для каждого писать?
но ведь мне и надо автоматизировать этот процесс!Как я вам показал — через указатели — сотню переменных автоматизировать тоже не получится. Там выравнивание всё поломает.
вспомните, что битовые переменные простенько так объединяются в BYTE или WORD....
считайте их одним байтомВ данном случае эти переменные даны неупакованными. И упаковывать их это та же головная боль, что и с занесением в промежуточный массив.
В кодесисе есть функции с переменным числом параметров, но пользователю почему-то не дают возможности их создавать.
ANDREY2002
26.09.2012, 23:42
Выходит , что не способа автоматизировать этот процесс ???????:confused:
ANDREY2002
27.09.2012, 22:40
случай, банальный
система управления климатом в здании :
два десятка различных аналоговых датчиков , десяток дискретных датчиков все они могут могут быть не исправны или сигнализировать какую либо неисправность + еще с десяток различных аварий из работы программы итого около 40 различных аварийных сигналов типа BOOL.
все эти аварии должны фиксироваться и заносится в архив, и в последствии выводится на СП270 и т.д.
блок программы который следит за изменением сигнала на 40 входах не удается автоматизировать: т.е. приходится писать для каждого входа
IF in_1=true THEN arr[1]:= 1;
IF in_2=true THEN arr[2]:= 2; и тд. 40 раз
а потом еще для передачи в панель обратно
out_1:=arr[1];......
и никаким циклом автоматизировать этот процесс не удается(
для лучшей диагностики планируется расширить список аварий до 100
Не верится , что в CoDeSys эту простую имхо задачу нельзя решить!
случай, банальный
система управления климатом в здании :
два десятка различных аналоговых датчиков , десяток дискретных датчиков все они могут могут быть не исправны или сигнализировать какую либо неисправность + еще с десяток различных аварий из работы программы итого около 40 различных аварийных сигналов типа BOOL.
все эти аварии должны фиксироваться и заносится в архив, и в последствии выводится на СП270 и т.д.
блок программы который следит за изменением сигнала на 40 входах не удается автоматизировать: т.е. приходится писать для каждого входа
IF in_1=true THEN arr[1]:= 1;
IF in_2=true THEN arr[2]:= 2; и тд. 40 раз
а потом еще для передачи в панель обратно
out_1:=arr[1];......
и никаким циклом автоматизировать этот процесс не удается(
для лучшей диагностики планируется расширить список аварий до 100
Не верится , что в CoDeSys эту простую имхо задачу нельзя решить!
а такой способ не поможет решить Вашу проблему автоматизации http://www.owen.ru/forum/attachment.php?attachmentid=6963&d=1347859220
Ну, если вы удостоверитесь, что булевые переменные идут одним куском без выравнивания либо сделайте поправку на него, то вот вам способ:
PROGRAM PLC_PRG
VAR
p: POINTER TO ARRAY [0..5] OF BOOL;
in0, in1, in2, in3, in4, in5: BOOL;
i: INT;
END_VAR
p := ADR(in0);
FOR i := 0 TO 5 DO
IF p^[i] THEN (* ... *) END_IF
END_FORИ на будущее: избегайте тавтологий вроде «IF in_1=true THEN» — достаточно написать «IF in_1 THEN».
--------->8---------
Проверил для 41 переменной. Вроде работает:
PROGRAM PLC_PRG
VAR
p: POINTER TO ARRAY [0..40] OF BOOL;
in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11, in12, in13, in14, in15, in16, in17, in18, in19, in20,
in21, in22, in23, in24, in25, in26, in27, in28, in29, in30, in31, in32, in33, in34, in35, in36, in37, in38, in39, in40: BOOL;
END_VAR
p := ADR(in0);
(* См. содержимое p^ при отладке *)Этим же способом и выводить можно:
p^[5] := TRUE; (* Делает in5 равным true *)
ANDREY2002
28.09.2012, 09:33
Спасибо огромное! Yegor и Сapzap.
Powered by vBulletin® Version 4.2.3 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot