вот откуда вопрос-то взялся
У меня есть куча параметров работы (далее - параметров), которые имеют одно общее свойство: их может читать оператор и-или комп сверху.
Сами по себе, это данные разных типов:
- флаги отдельных свойств (ну, там можно BYTE юзать);
- короткие пременные, тоже однобайтных хватает;
- длинные переменные, как со знаком, так и без, некоторые требуют аж 4-х байт;
- временнЫе данные, такие как время, дата, длительность разных пауз и задержек (до десятков секунд);
- флоаты тоже. по сути работают. но я их постараюсь убрать и в качестве параметров не использовать.
Эти данные имеют разные изменяемости:
- неизменяемые переменные (типа номер версии ПО, задается при компилировании);
- изменяемые программой, но не оператором (например, результат измерения или фаза работы);
- изменяемые оператором и-или программой, но с разной "разрешительной системой", например, изменяемые только с кодом доступа или как попало;
Эти данные еще имеют и разные свойства в смысле сохраняемости. Часть из них должна быть RETAIN, для остальных это бессмысленно. Часть параметров сохраняется вообще не в ПЛК, а в другом узле сети.
Ну, и другие мелкие различия в порядке их редактирования, автоматического изменения и прочее - этим, скорее всего, придется пожертвовать ради великой Цели.
А Цель такова: сделать работу с просмотром и редактированием параметров в одном участке кода. То есть, работать с параметром при его редактировании по его индексу. И все. Остальное предполагается извлекать из структуры PARSCRIPT, в которой есть вся необходимая инфо.
В старом проекте (не на ПЛК) были просто огромные SWITCH-и и на каждый параметр свой CASE. Но там хоть привычная форма представления программ, в человеческих редакторах. В КОДЕСИС же (при всем уважении!) работать с огромными текстами неудобно.
Да и вообще, считайте это моим капризом. "Хочу иконки, несмотря на социализм" :)
Для реализации Цели я создаю такие элементы:
1. Описание параметров.
Код:
TYPE PARSCRIPT :
STRUCT
Numb: BYTE; (* Номер параметра по ЭД, 0...255 *)
Point: BYTE; (* Формат вывода: 0, 1, 2, 3 знака справа от точки *)
Mdf: BYTE; (* 0 prog RO, 1 user RO, 2 RW, 3 R(W в СТОПЕ), 4 R(W с паролем) *)
Node: BYTE; (* Место хранения параметра, 0 - в ПЛК, 1 - в ТП *)
Mini: DINT; (* Границы значения параметра *)
Maxi: DINT;
Ptr: POINTER TO DINT;(* Указатель на параметр *)
Name: STRING(10); (* Текст имени *)
END_STRUCT
END_TYPE
2. Массив структур размером с количество параметров:
Код:
VAR_GLOBAL
apsPar: ARRAY [0..MAX_PAR_NMB] OF PARSCRIPT;
END_VAR
Этот массив с помощью функции set, подсказанной Учителем, заполняю при старте константами. В том числе, на место Ptr записываю адреса переменных-параметров:
в фунции set есть строка
Код:
apsPar[ iParIndx].Name := Name;
и функция вызывается многократно, на все параметры:
Код:
set( 101, 2, 0, 0, 0, 9999, ADR(Dummy), 'Версия ПЛК');
set( 102, 2, 0, 0, 0, 9999, ADR(Dummy), 'Версия ТП');
set( 103, 0, 4, 0, 1, 31, ADR(_103_Addr_IP), 'Адр с ИП');
set( 104, 0, 4, 0, 0, 5, ADR(_104_Baud_IP), 'Скор с ИП');
3. Собственно параметры, разных типов, сохраняемые и нет:
Код:
VAR_GLOBAL RETAIN
(* Сохраняемые П А Р А М Е Т Р Ы работы ПЛК *)
_103_Addr_IP: BYTE := 1; (*Адрес для работы с ИП320 *)
_104_Baud_IP: BYTE := 5; (*Код 0-5 скорости работы *)
...
(* Конец области задания П А Р А М Е Т Р О В *)
END_VAR
VAR_GLOBAL
(* Не сохраняемые П А Р А М Е Т Р Ы работы ПЛК *)
_120_ADC: DINT; (* Код АЦП *)
_170_Phase: BYTE; (* Фаза работы *)
...
_185_Time2Unld: TIME; (* Время до разгрузки *)
_186_Errors: WORD; (* Слово ощибок (аварий) *)
(* Конец области задания П А Р А М Е Т Р О В *)
END_VAR
Дальше я еще не написал, т.е. все неприятности по поводу чтения и редактирования параметров оператором - впереди.
Но уже сейчас понятно, что объявление в PARSCRIPT
Код:
Ptr: POINTER TO DINT; (* Указатель на параметр *)
вызовет проблемы для тех параметров, которые вовсе не DINT.
Как же быть? Как доступаться к параметрам, имея на руках только указатель, если параметры разные по типам?