Как Вы, возможно, знаете PLCOpen разработали документ Creating PLCopen Compliant Libraries, в котором описаны стандартные интерфейсы и поведения функциональных блоков разработанных на языках стандарта МЭК-61131 (всем нам знакомые FBD, CFC, ST и т.д.).
Не так давно этот документ был переведен на русский язык (доступен по ссылке).
В стандарте приведены примеры для всех "моделей поведения", но их использование в проекте затруднено т.к. все примеры приведены в виде картинок и текст придется перенабирать вручную.
В этой теме я буду постепенно выкладывать исходный код ФБ (на языке ST) тех моделей поведения, которые использовал в работе.
Так Вы сможете просто
скопировать перечисление, содержащее состояния ФБ в Ваш проект;
скопировать "скелет" ФБ;
доработать "скелет" ФБ в соответствии с Вашей задачей (места, которые необходимо доработать под задачу выделил комментариями (* TODO: *)).
без необходимости перевводить код ФБ вручную.
Если Вы использовали модель поведения, которой еще нет в теме - присылайте исходный код, я добавлю его в тему.
Итак:
перечисление, содержащее все состояния ФБ:
Префикс BM - сокращение от Behavior model (модель поведения)
Код:
(*
Перечисление, содержащее все состояния ФБ
*)
TYPE BM_STATES :
(
BM_DORMANT := 0, (* Ожидание запуска *)
BM_EXECUTING := 1, (* Выполнение операции *)
BM_DONE := 2, (* Завершение операции *)
BM_ERROR := 3, (* Ошибка *)
BM_RESETTING := 4, (* Переинициализация *)
BM_ABORTING := 5, (* Прерывание работы ФБ *)
BM_ABORTED := 6 (* Работа ФБ прервана *)
);
END_TYPE
ETrig
Старт по переднему фронту;
Нет возможности прерывания до окончания работы блока;
m_xNeedToChangeState := TRUE;
WHILE m_xNeedToChangeState DO
m_xNeedToChangeState := FALSE;
CASE m_eState OF
BM_DORMANT:
IF xExecute THEN
xBusy := TRUE;
m_eState := BM_EXECUTING;
m_xNeedToChangeState := TRUE;
(* TODO: запомнить состояние остальных входов *)
END_IF
BM_EXECUTING:
(* TODO: m_xIsExecutionDone должно стать TRUE, когда выполнение операции завершено успешно *)
m_xIsExecutionDone := TRUE;
(* TODO: m_xIsExecutionFail должно стать TRUE, когда возникла ошибка выполнения операции *)
m_xIsExecutionFail := FALSE;
IF m_xIsExecutionFail THEN
m_eState := BM_ERROR;
m_xNeedToChangeState := TRUE;
ELSIF m_xIsExecutionDone THEN
m_eState := BM_DONE;
m_xNeedToChangeState := TRUE;
END_IF
BM_DONE:
IF xDone AND (m_xResetRequest OR NOT xExecute) THEN
m_eState := BM_RESETTING;
m_xNeedToChangeState:= TRUE;
ELSE
xBusy := FALSE;
xDone := TRUE;
m_xResetRequest := NOT xExecute;
m_xNeedToChangeState:= FALSE;
END_IF
BM_ERROR:
IF xError AND (m_xResetRequest OR NOT xExecute) THEN
m_eState := BM_RESETTING;
m_xNeedToChangeState:= TRUE;
ELSE
xBusy := FALSE;
xError := TRUE;
m_xResetRequest := NOT xExecute;
m_xNeedToChangeState:= FALSE;
END_IF
BM_RESETTING:
(* TODO: освобождение ресурсов здесь *)
xBusy := FALSE;
xDone := FALSE;
xError := FALSE;
m_eState := BM_DORMANT;
m_xNeedToChangeState := m_xResetRequest;
m_xResetRequest := FALSE;
m_xIsExecutionDone := FALSE;
m_xIsExecutionFail := FALSE;
END_CASE
END_WHILE
ETrigA
Старт по переднему фронту;
Есть возможность прерывания до окончания работы блока;
m_xNeedToChangeState := TRUE;
WHILE m_xNeedToChangeState DO
m_xNeedToChangeState := FALSE;
CASE m_eState OF
BM_DORMANT:
IF xExecute THEN
xBusy := TRUE;
m_eState := BM_EXECUTING;
m_xNeedToChangeState := TRUE;
(* TODO: запомнить состояние остальных входов *)
END_IF
BM_EXECUTING:
(* TODO: m_xIsExecutionDone должно стать TRUE, когда выполнение операции завершено успешно *)
m_xIsExecutionDone := TRUE;
(* TODO: m_xIsExecutionFail должно стать TRUE, когда возникла ошибка выполнения операции *)
m_xIsExecutionFail := FALSE;
IF m_xIsExecutionFail THEN
m_eState := BM_ERROR;
m_xNeedToChangeState := TRUE;
ELSIF m_xIsExecutionDone THEN
m_eState := BM_DONE;
m_xNeedToChangeState := TRUE;
END_IF
IF xAbort THEN
m_xNeedToChangeState := TRUE;
m_eState := BM_ABORTING;
END_IF
BM_DONE:
IF xDone AND (m_xResetRequest OR NOT xExecute) THEN
m_eState := BM_RESETTING;
m_xNeedToChangeState:= TRUE;
ELSE
xBusy := FALSE;
xDone := TRUE;
m_xResetRequest := NOT xExecute;
m_xNeedToChangeState:= FALSE;
END_IF
BM_ERROR:
IF xError AND (m_xResetRequest OR NOT xExecute) THEN
m_eState := BM_RESETTING;
m_xNeedToChangeState:= TRUE;
ELSE
xBusy := FALSE;
xError := TRUE;
m_xResetRequest := NOT xExecute;
m_xNeedToChangeState:= FALSE;
END_IF
BM_RESETTING:
(* TODO: освобождение ресурсов здесь *)
xBusy := FALSE;
xDone := FALSE;
xError := FALSE;
m_eState := BM_DORMANT;
m_xNeedToChangeState := m_xResetRequest;
m_xResetRequest := FALSE;
m_xIsExecutionDone := FALSE;
m_xIsExecutionFail := FALSE;
m_xIsAbortingDone := FALSE;
m_xIsAbortingFail := FALSE;
BM_ABORTING:
(* TODO: m_xIsAbortingDone должно стать TRUE, когда прерывание операции выполнено *)
m_xIsAbortingDone := TRUE;
(* TODO: m_xIsAbortingFail должно стать TRUE, когда возникла ошибка прерывания операции *)
m_xIsAbortingFail := FALSE;
IF m_xIsAbortingFail THEN
m_eState := BM_ERROR;
m_xNeedToChangeState := TRUE;
ELSIF m_xIsAbortingDone THEN
m_eState := BM_ABORTED;
m_xNeedToChangeState:= TRUE;
END_IF
BM_ABORTED:
IF xAborted AND (m_xResetRequest OR (NOT xExecute)) THEN
m_eState := BM_RESETTING;
m_xNeedToChangeState:= TRUE;
ELSE
xBusy := FALSE;
xAborted := TRUE;
m_xResetRequest := NOT xExecute;
m_xNeedToChangeState:= FALSE;
END_IF
END_CASE
END_WHILE
P.S. Не смотря на то, что в теме указано "Модели поведения в CODESYS 2.3". Этот же исходный код будет работать и в CODESYS 3.5.
Заготовка оформления:
Название модели поведения
Краткое описание блока
Исходный код:
Интерфейс ФБ
Код:
Тело ФБ
Код:
Последний раз редактировалось Евгений Кислов; 13.03.2019 в 19:44.
OSCAT.ru читать стандарты и статьи по автоматизации на русском без регистрации и СМС