ЖУРНАЛ «СТА» №2/2006

Помимо пользовательских методов и стандартной реали- зации, функциональный блок включает два предопреде- лённых метода: Init и Exit . Init вызывается неявно для всех экземпляров всех функциональных блоков после загрузки кода приложения или «холодного» рестарта контроллера. Exit вызывается перед «горячим» обновлением кода экзем- пляра, перед сбросом или управляемым отключением пита- ния ПЛК. Например, его можно применить для корректно- го завершения работы. Для упрощения правила видимости заданы жёстко: Уже существующий класс может быть дополнен с помо- щью ключевого слова EXTENTS . FUNCTION_BLOCK MonitoredPump EXTENTS Pump VAR MonitoredState: (OK, Error); END_VAR METHOD HasError : BOOL ; HasError := MonitoredState <> OK; END_METHOD END_FUNCTION_BLOCK PROGRAM Main VAR Pump1: Pump; Pump2: MonitoredPump; END_VAR Pump1.Start(Forward); IF NOT Pump2.HasError THEN (* Все методы базового класса доступны *) Pump1.Start(Backward); END_IF END_PROGRAM Однако реальную мощь ООП даёт возможность создания интерфейсов. Под интерфейсом понимается набор мето- дов, работающих с одинаковыми параметрами, но разными реализациями для разных функциональных блоков. Интер- фейс можно передать в качестве параметра, и программный компонент (POU) не будет в действительности заботиться о том, какой функциональный блок им применяется. Следующий пример иллюстрирует данную технику: INTERFACE Drive METHOD HasError : BOOL ; END_METHOD METHOD Home : BOOL ; END_METHOD METHOD MoveAbsolute : BOOL ; VAR_INPUT Pos: DINT ; END_VAR END_METHOD END_INTERFACE Теперь мы можем написать несколько функциональных блоков, реализующих интерфейс Drive (привод) с помощью ключевого слова IMPLEMENTS . FUNCTION_BLOCK CANDrive IMPLEMETS Drive VAR CANId: DINT ; State: (OK, ParamError, DriveError, CommError); InHoming: BOOL ; END_VAR METHOD HasError : BOOL ; HasError: State <> OK; END_METHOD METHOD Home : BOOL ; IF NOT InHoming THEN WriteSDO(CANId, 16#4711, 16#02, 1); (*Команда на исх.*) InHoming := TRUE ; ELSE Home := ReadSDO(CANId, 16#4711, 16#03); InHoming := NOT Home; END_IF END_METHOD METHOD MoveAbsolute : BOOL ; VAR_INPUT Pos: DINT ; END_VAR ... (* Реализация абсолютного перемещения *) END_METHOD METHOD SetCanId : BOOL ; VAR_INPUT Id: DINT ; END_VAR CANId := Id; END_METHOD END_FUNCTION_BLOCK Как можно видеть, все методы интерфейса Drive напол- нены специальными реализациями, построенными на CANсообщениях. Сверх того здесь присутствуют некото- рые специфические переменные и методы. В данном случае это метод, устанавливающий CAN Id. Далее мы могли бы описать еще один вид привода, например аналоговый (AnalogDrive). В нём можно реализовывать методы совер- шенно иначе, чем для цифрового привода (CANDrive). Теперь можно написать функциональный блок, получаю- щий интерфейс в качестве параметра: FUNCTION_BLOCK InitMove VAR_INPUT D: Drive; Pos: INT ; END_VAR VAR_OUTPUT Done: BOOL ; END_VAR IF Drive.Home() THEN IF Drive.MoveAbsolute(Pos) THEN Done := TRUE ; END_IF END_IF END_FUNCTION_BLOCK 91 СТА 2/2006 www.cta.ru В З АПИС Н УЮ К НИЖК У ИНЖЕ Н Е РА Тип элемента Внешний доступ на чтение Внешний доступ на запись Внешний вызов VAR — — — VAR_INPUT — √ — VAR_OUTPUT √ — — METHOD — — √

RkJQdWJsaXNoZXIy MTQ4NjUy