Версия для печати

Вариант универсального таймера типов SD SP SE SS

Дата: 2014-07-09

Добавлено: nelegal34

Тема: SCL



timerp



Вариант универсального таймера, с отсчетом времени не по SampleTime (как сделано в PCS7), а по тикам ПЛК.





Описание:





Проблематика:



Столкнулся с некоторыми проблемами при анализе существующего/функционирующего проекта. Проект был сделан с применением CFC, но блоки были раскиданы по OB как бог на душу положил, т.е. часть в OB32, часть в других, причем никакого соблюдения последовательностей.



Самая печаль была в том, что часть блоков была в OB1, но временные задержки были реализованы на стандартном блоке TIMER_P (CFC_LIB - FB5), естественно возникали проблемы с пропусками импульсов и ложными не срабатываниями.



Решение:



Написал блочок, аналогичный FB5, но работающий по тикам ПЛК, не зависит от размещения и типа OB (TIMER_P - корректно работает только в циклической OB, т.к. использует вход SAMPLE_T, который обновляется при компиляции CFC).





Исходный текст блока:



FUNCTION_BLOCK FB1212
TITLE = 'Таймер на базе системного времени'
//QM0 (SP) - Таймер "Импульс"
//QM1 (SE) - Таймер "Удлиненный импульс"
//QM2 (SD) - Таймер "Задержка включения"
//QM3 (SS) - Таймер "Задержка включения с памятью"
VERSION: '1.0'
AUTHOR: 'EEA'
NAME: 'TM'
FAMILY: 'CA'
KNOW_HOW_PROTECT
{S7_tasklist:='OB100'}
VAR_INPUT
    SP:TIME:=T#0MS;
    S:BOOL;
    R:BOOL;
END_VAR
VAR_OUTPUT
    PV:TIME;
    QM0:BOOL;
    QM1:BOOL;
    QM2:BOOL;
    QM3:BOOL;
END_VAR
VAR
    _S  :BOOL;
    _F  :BOOL;
    _T0 :TIME;
    _T1 :TIME;
    _RV :INT;
    _TOP_SI
        :STRUCT
            EV_CLASS:BYTE;
            EV_NUM  :BYTE;
            PRIORITY:BYTE;
            NUM     :BYTE;
            TYP2_3  :BYTE;
            TYP1    :BYTE;
            ZI1     :WORD;
            ZI2_3   :DWORD;
        END_STRUCT;
    _START_UP_SI
        :STRUCT
            EV_CLASS:BYTE;
            EV_NUM  :BYTE;
            PRIORITY:BYTE;
            NUM     :BYTE;
            TYP2_3  :BYTE;
            TYP1    :BYTE;
            ZI1     :WORD;
            ZI2_3   :DWORD;
        END_STRUCT;
END_VAR
CONST
    _TM:=T#24D_20H_31M_23S_647MS;
END_CONST
 
BEGIN
_RV:=RD_SINFO(TOP_SI:=_TOP_SI, START_UP_SI:=_START_UP_SI);
IF _TOP_SI.NUM=B#16#64 OR (S & NOT _S) THEN _T1:=TIME_TCK(); _T0:=_T1; END_IF;
IF S & NOT _S THEN _F:=1; PV:=SP; END_IF;
_S:=S;
 
IF R OR SP<=T#0MS THEN
    PV:=T#0MS; _S:=0; _F:=0;
ELSE
    IF PV<>T#0MS THEN
        _T1:=TIME_TCK();
        IF (_T1-_T0)>=T#0MS THEN PV:=PV-(_T1-_T0); ELSE PV:=PV-(_TM-_T0)-_T1; END_IF; _T0:=_T1;
        IF PV<=T#0MS THEN PV:=T#0MS; END_IF;
    END_IF;
END_IF;
 
QM0:=NOT R & S & PV>T#0MS;
QM1:=NOT R & PV>T#0MS;
QM2:=NOT R & S & PV<=T#0MS;
QM3:=NOT R & _F & PV<=T#0MS;
END_FUNCTION_BLOCK



Блок в стадии внедрения на реальном объекте - используйте с осторожностью.







Просмотров: 3240

Комментарии к материалу

Ваш будет первым.

Добавить комментарий

Ваше имя:

Текст комментария (4000 max):

Введите сумму с картинки: