diff -r 000000000000 -r fb772792efd1 lib/timer.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/timer.txt Wed Jan 31 15:32:38 2007 +0100 @@ -0,0 +1,280 @@ +(* + * (c) 2005 Mario de Sousa + * + * Offered to the public under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * This code is made available on the understanding that it will not be + * used in safety-critical situations without a full and competent review. + *) + +(* + * An IEC 61131-3 IL and ST compiler. + * + * Based on the + * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10) + * + *) + +(* + * This is part of the library conatining the functions + * and function blocks defined in the standard. + * + * Timer Function Blocks + * --------------------- + * + * NOTE: The timing diagrams in the comments were taken from the + * IEC 61131-3 standard. + *) + + + +(**************************************************************** + + TP - pulse timing - state machine + + + +--------+ ++ ++ +--------+ + IN | | || || | | + --+ +-----++-++---+ +--------- + t0 t1 t2 t3 t4 t5 + +----+ +----+ +----+ + Q | | | | | | + --+ +---------+ +--+ +------------- + t0 t0+PT t2 t2+PT t4 t4+PT + PT +---+ + +---+ + : / | /| / | + ET : / | / | / | + : / | / | / | + : / | / | / | + 0-+ +-----+ +--+ +--------- + t0 t1 t2 t4 t5 + + + 2 +---+ + +---+ +STATE 1 +----+ | +----| +----+ | + 0 --+ +-----+ +--+ +--------- + + +****************************************************************) + +FUNCTION_BLOCK TP + VAR_INPUT + IN : BOOL; (* first input parameter *) + PT : TIME; (* second input parameter *) + END_VAR + VAR_OUTPUT + Q : BOOL := FALSE; (* first output parameter *) + ET : TIME := T#0s; (* second output parameter *) + END_VAR + + VAR + STATE : SINT := 0; (* internal state: 0-reset, 1-counting, 2-set *) + PREV_IN : BOOL := FALSE; + CURRENT_TIME, START_TIME : TIME; + END_VAR + + {data__->CURRENT_TIME = __CURRENT_TIME;} + + IF ((STATE = 0) AND NOT(PREV_IN) AND IN) (* found rising edge on IN *) + THEN + (* start timer... *) + STATE := 1; + Q := TRUE; + START_TIME := CURRENT_TIME; + + ELSIF (STATE = 1) + THEN + IF ((START_TIME + PT) <= CURRENT_TIME) + THEN + STATE := 2; + Q := FALSE; + ET := PT; + ELSE + ET := CURRENT_TIME - START_TIME; + END_IF; + END_IF; + + IF ((STATE = 2) AND NOT(IN)) + THEN + ET := T#0s; + STATE := 0; + END_IF; + + + PREV_IN := IN; + +END_FUNCTION_BLOCK + + + + +(**************************************************************** + + TON - On-delay timing - state machine + + + +--------+ +---+ +--------+ + IN | | | | | | + --+ +--------+ +---+ +------------- + t0 t1 t2 t3 t4 t5 + +---+ +---+ + Q | | | | + -------+ +---------------------+ +------------- + t0+PT t1 t4+PT t5 + PT +---+ +---+ + : / | + / | + ET : / | /| / | + : / | / | / | + : / | / | / | + 0-+ +--------+ +---+ +------------- + t0 t1 t2 t3 t4 t5 + + + 2 +---+ +---+ +STATE 1 +----+ | +---+ +----+ | + 0 --+ +--------+ +---+ +------ + + +****************************************************************) + + +FUNCTION_BLOCK TON + VAR_INPUT + IN : BOOL; (* first input parameter *) + PT : TIME; (* second input parameter *) + END_VAR + VAR_OUTPUT + Q : BOOL := FALSE; (* first output parameter *) + ET : TIME := T#0s; (* second output parameter *) + END_VAR + + VAR + STATE : SINT := 0; (* internal state: 0-reset, 1-counting, 2-set *) + PREV_IN : BOOL := FALSE; + CURRENT_TIME, START_TIME : TIME; + END_VAR + + {data__->CURRENT_TIME = __CURRENT_TIME;} + + IF ((STATE = 0) AND NOT(PREV_IN) AND IN) (* found rising edge on IN *) + THEN + (* start timer... *) + STATE := 1; + Q := FALSE; + START_TIME := CURRENT_TIME; + + ELSE + (* STATE is 1 or 2 !! *) + IF (NOT(IN)) + THEN + ET := T#0s; + Q := FALSE; + STATE := 0; + + ELSIF (STATE = 1) + THEN + IF ((START_TIME + PT) <= CURRENT_TIME) + THEN + STATE := 2; + Q := TRUE; + ET := PT; + ELSE + ET := CURRENT_TIME - START_TIME; + END_IF; + END_IF; + + END_IF; + + PREV_IN := IN; + +END_FUNCTION_BLOCK + + + + + +(**************************************************************** + + TOFF - Off-delay timing - state machine + + + +--------+ +---+ +--------+ + IN | | | | | | + ---+ +--------+ +---+ +----------- + t0 t1 t2 t3 t4 t5 + +-------------+ +---------------------+ + Q | | | | + ---+ +---+ +------ + t0 t1+PT t2 t5+PT + PT +---+ +------ + : / | + / + ET : / | /| / + : / | / | / + : / | / | / + 0------------+ +---+ +--------+ + t1 t3 t5 + + + 2 +---+ +------ +STATE 1 +----+ | +---+ +----+ + 0 -------------+ +---+ +--------+ + + +****************************************************************) + +FUNCTION_BLOCK TOFF + VAR_INPUT + IN : BOOL; (* first input parameter *) + PT : TIME; (* second input parameter *) + END_VAR + VAR_OUTPUT + Q : BOOL := FALSE; (* first output parameter *) + ET : TIME := T#0s; (* second output parameter *) + END_VAR + + VAR + STATE : SINT := 0; (* internal state: 0-reset, 1-counting, 2-set *) + PREV_IN : BOOL := FALSE; + CURRENT_TIME, START_TIME : TIME; + END_VAR + + {data__->CURRENT_TIME = __CURRENT_TIME;} + + IF ((STATE = 0) AND PREV_IN AND NOT(IN)) (* found falling edge on IN *) + THEN + (* start timer... *) + STATE := 1; + START_TIME := CURRENT_TIME; + + ELSE + (* STATE is 1 or 2 !! *) + IF (IN) + THEN + ET := T#0s; + STATE := 0; + + ELSIF (STATE = 1) + THEN + IF ((START_TIME + PT) <= CURRENT_TIME) + THEN + STATE := 2; + ET := PT; + ELSE + ET := CURRENT_TIME - START_TIME; + END_IF; + END_IF; + + END_IF; + + Q := IN OR (STATE = 1); + PREV_IN := IN; + +END_FUNCTION_BLOCK +