czwartek, 5 lutego 2015

Podstawy ST - podprogramy, funkcje, bloki funkcyjne

Wymienione w tytule podprogramy, funkcje i bloki funkcyjne to trzy podstawowe formy, w jakich można umieścić w programie własne instrukcje. Każda dzieli się na dwie części, jedną z deklaracją oraz drugą, gdzie umieszczamy kod.  Przyjrzyjmy się im po kolei.

PODPROGRAMY

Podstawa to podprogramy. Jeden z nich wykonywany jest w pętli. Nie zwracają nic. Nie przyjmują parametrów. Podstawowa deklaracja:

PROGRAM Program1
VAR
END_VAR


Warto zaznaczyć, że zmienne umieszczone w sekcji VAR są pamiętane przy kolejnych wywołaniach.

Przykład użycia:

Program1();


FUNKCJE

Funkcje to też jest krótka piłka. Zwracają wartość wybranego typu. Przyjmują parametry. Podstawowa deklaracja:

FUNCTION Funkcja1 : TypZwracany
VAR_INPUT
END_VAR
VAR
END_VAR


Zwrócenia wartości dokonujemy poprzez zastosowania operatora przypisania z nazwą funkcji. Przykładowa funkcja sumująca dwie liczby mogłaby wyglądać tak:

FUNCTION Suma : INT
VAR_INPUT
     a : INT;
     b : INT;
END_VAR
VAR
END_VAR
Suma := a + b;


Użycie tej funkcji:

wynik := Suma(a := 10, b := 5);

BLOKI FUNKCYJNE

Nie jest łatwo wytłumaczyć czym są bloki funkcyjne. Jest to konstrukcja charakterystyczna bardziej dla PLC niż dla klasycznego programowania. Posiada parametry wejściowe i wyjściowe. Jest deklarowany jak zmienna, ale wywoływany jak procedura, a każde takie wywołanie powoduje wykonanie obecnego w nim kodu. Podstawowa deklaracja:

FUNCTION_BLOCK Blok1
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
END_VAR


Tylko zmienne wewnętrzne są pamiętane przy kolejnych wywołaniach.

Przykład bloku funkcyjnego:
FUNCTION_BLOCK FB_Pomiar
VAR_INPUT
    In: REAL;
    Reset: BOOL;
END_VAR
VAR_OUTPUT
    Out: REAL;
END_VAR
VAR
    avg: REAL;
    count: INT := 1;
END_VAR
IF Reset OR count + 1 < count THEN
    count := 1;
    avg := In;
ELSE
    count := count + 1;
    avg := avg + ((In - avg) / INT_TO_REAL(count));
END_IF
Out := avg;

Przykład podprogramu korzystającego z tego bloku:
PROGRAM Pomiary
VAR
    Pomiar1 : FB_Pomiar;
    Wejscie : REAL;
    Srednia : REAL;
END_VAR
Pomiar1(In := Wejscie, Reset := FALSE, Out => Srednia);