ST
(Structured Text) è un linguaggio di alto livello basato sul testo per la programmazione di sistemi di automazione. I semplici costrutti standard consentono una programmazione rapida ed efficiente. ST
utilizza molte qualità tradizionali dei linguaggi di alto livello, tra cui variabili, operatori, funzioni ed elementi per il controllo del flusso del programma.
Che cos'è il testo strutturato ?
Nessun altro linguaggio di programmazione può sostituire ST
. Ogni linguaggio di programmazione presenta vantaggi e svantaggi. Il vantaggio principale di ST
è che si possono programmare facilmente calcoli matematici complessi.
Il testo strutturato è caratterizzato dalle seguenti caratteristiche:
ST
è stato progettato per funzionare con gli altri linguaggi di programmazione dei PLC. Ad esempio, un programma di logica ladder può chiamare una subroutine di Testo strutturato
.
i := 0;
REPEAT
i := i + 1;
UNTIL i > 10;
END_REPEAT;
Nell'editor IEC la dichiarazione delle variabili e il corpo del programma sono definiti separatamente. Non è necessario scrivere
PROGRAMMA <nome>
eFINE_PROGRAMMA
, ma solo il codice sorgente.
Quando si definiscono le variabili, è necessario specificare il tipo di dichiarazione. Si tratta dell'ambito delle variabili. Le dichiarazioni VAR_INPUT
, VAR_OUTPUT
e VAR_IN_OUT
sono utilizzate per le variabili che vengono passate come argomenti al programma o alla funzione.
Dichiarazione | Descrizione |
---|---|
VAR |
La dichiarazione generale di variabile locale |
VAR_INPUT |
Definisce un elenco di variabili per una funzione |
VAR_OUTPUT |
Definisce le variabili di uscita da una funzione |
VAR_IN_OUT |
Definisce le variabili che sono sia input che output di una funzione |
VAR_TEMP |
Variabili temporanee |
VAR_GLOBAL |
Variabili globali definite nella configurazione |
END_VAR |
Segna la fine di una dichiarazione di variabile |
Tabella 3.1 - Dichiarazioni di ambito di una variabile
Le parole chiave del tipo di variabile possono essere completate dalla parola chiave RETAIN
(cioè: VAR_INPUT RETAIN
).
<Identifier> { AT <address> } : <type> { := <initialization> };
le parti tra gli spazi { } sono opzionali .
Le regole elencate nel seguente riquadro di testo relative all'uso multiplo devono essere considerate
un identificatore
non deve essere duplicato localmente .
un identificatore
non deve essere indetico a qualsiasi parola chiave .
globalmete un identificatore
possono essere utilizzate in modo plurale, quindi una variabile locale può avere lo stesso nome di una globale. In questo caso, all'interno di un POU, la variabile locale avrà la priorità.
la variabile può essere direttamente conessa nel definire indirizzo della parola chiave
AT
<address>
.
Un Tipo di dati
valido, facoltativamente esteso da un := <inizializzazione>
.
Durante la programmazione è possibile utilizzare tipi di dati standard, tipi di dati definiti dall'utente o istanze di blocchi funzione. A ogni identificatore viene assegnato un Tipo di dati
che determina la quantità di spazio di memoria riservato e il tipo di valori memorizzati.
I tipi di dati standard IEC61131-3 sono supportati da Sirius ES - IEC EDITOR. Si veda quanto segue.
Alle variabili di tipo BOOL
possono essere assegnati i valori TRUE
(1
) e FALSE
(0
).
Di seguito è riportato un elenco di tutti i tipi di dati INTEGER
disponibili. Ciascuno dei diversi tipi di numero copre un diverso intervallo di valori. Ai tipi di dati INTEGER
si applicano le seguenti limitazioni di intervallo:
Tipo di dati | Valore inferiore | Valore superiore | Bit utilizzati | |
---|---|---|---|---|
BYTE |
0 | 255 | 8 | |
WORD |
0 | 65535 | 16 | |
DWORD |
0 | 4294967295 | 32 | |
LWORD |
0 | 264-1 | 64 | |
SINT |
-128 | 127 | 8 | |
USINT |
0 | 255 | 8 | |
INT |
- | 32768 | 32767 | 16 |
UINT |
0 | 65535 | 16 | |
DINT |
-2147483648 | 2147483647 | 32 | |
UDINT |
0 | 4294967295 | 32 | |
LINT |
-263 | 263-1 | 64 | |
ULINT |
0 | 264-1 | 64 |
Tabella 3.2 Tipi di dati INTEGER
come risultato quando i tipi piu grandi vengono covertiti in tipi piu piccoli , si possono perdere delle informazioni.
I tipi di dati REAL
e LREAL
sono i cosiddetti tipi a virgola mobile. Sono necessari per rappresentare i numeri razionali. 32 bit di spazio di memoria sono riservati a REAL
e 64 bit a LREAL
.
Data Type | Lower value | Upper Value | Bit used |
---|---|---|---|
REAL |
1.401e-45 | 3.403e+38 | 32 |
LREAL |
2.2250738585072014e-308 | 1.7976931348623158e+308 | 64 |
Table 3.3 REAL - LREAL data types
Una variabile di tipo Data Type
STRING
può contenere qualsiasi stringa di caratteri. La voce size della dichiarazione determina lo spazio di memoria da riservare alla variabile. Si riferisce al numero di caratteri della stringa e può essere inserita tra parentesi o tra parentesi quadre. Se non viene specificata alcuna dimensione, verrà utilizzata la dimensione predefinita di 80 caratteri.
La lunghezza della stringa non è limitata, ma le funzioni di stringa possono elaborare solo stringhe di 1 - 255 caratteri. Se una variabile viene inizializzata con una stringa troppo lunga per il tipo di dati della variabile, la stringa verrà tagliata da destra a sinistra.
In Sirius ES - IEC EDITOR la specifica della dimensione non è supportata.
WSTRING
Data Type
è un estesione del IEC 61131-3 standard.
Si differenzia dal tipo standard STRING
(ASCII) per essere interpretato in formato Unicode e per aver bisogno di 2 byte per ogni carattere e di 2 byte di spazio di memoria extra (1 solo nel caso di una STRING).
I tipi di dati TIME
, TIME_OF_DAY
(abbreviato TOD
), DATE
e DATE_AND_TIME
(abbreviato DT
) sono gestiti internamente come DWORD
. Il tempo è indicato in millisecondi in TIME
e TOD
. Il tempo in TOD
inizia alle 12:00. Il tempo è dato in secondi in DATE
e DT
a partire dal 1° gennaio 1970 alle 12:00.
Le costanti TIME
sono generalmente utilizzate per far funzionare i moduli timer standard. La costante temporale TIME
ha una dimensione di 32 bit ed è conforme allo standard IEC 61131-3.
Sintassi per la costante TIME
:
t#<time declaration>
Al posto di t#
si possono usare anche i seguenti termini T#
, time
, TIME
.
La dichiarazione TIME
può includere le seguenti unità di tempo. Queste devono essere usate nella seguente sequenza, ma non è obbligatorio usarle tutte.
d
- giornih
- orem
- minutis
- secondims
- millisecondiTIME1 := t#14ms;
Oltre ai tipi di dati standard, l'utente può definire tipi di dati speciali all'interno di un progetto.
Queste definizioni sono possibili creando oggetti Nuovo tipo di dati
nel nodo Tipo di dati
del menu Progetto
.
I tipi di dati definiti dall'utente possono essere:
In Sirius ES - IEC Editor i tipi di dati non sono dichiarati in modalità testo, ma con forme specifiche per ogni tipo.
Nei linguaggi di alto livello come ST
, si possono usare semplici costrutti per confrontare le variabili. Questi restituiscono il valore VERO o FALSO.
Simbolo | Espressione di confronto logico | Esempio |
---|---|---|
= |
Uguale a | IF (a = b) THEN |
<> |
Non uguale a | IF (a <> b) THEN |
> |
Maggiore di | IF (a > b) THEN |
>= |
Maggiore o uguale a | IF (a >= b) THEN |
< |
Minore di | IF (a < b) THEN |
<= |
Minore o uguale a | IF (a <= b) THEN |
Tabella 3.5 Operatori di confronto
Il tipo di dati
è un fattore molto importante. Si veda la seguente tabella:
Sono disponibili i seguenti operatori booleani, in linea con lo standard IEC1131-3:
Tipi consentiti: BOOL
, BYTE
, WORD
, DWORD
, LWORD
.
Simbolo | Descrizione | Esempio |
---|---|---|
AND |
AND Bitwise AND di operandi bit. Se i bit di ingresso sono ciascuno 1, il bit risultante sarà 1, altrimenti 0. |
var1 := 16#4D AND 16#7F; |
OR |
Bitwise OR di operandi bit. Se almeno uno dei bit di ingresso è 1, il bit risultante sarà 1, altrimenti 0. |
Var1 := 16#4D OR 16#7F; |
XOR |
Operazione XOR bitwise di operandi bit. Se solo uno dei bit di ingresso è 1, il bit risultante sarà 1; se entrambi o nessuno sono 1, il bit risultante sarà 0. |
Var1 := 16#4D XOR 16#7F; |
NOT |
Operazione bitwise NOT di un operando bit. Il bit risultante sarà 1 se il corrispondente bit di ingresso è 0 e viceversa. |
Var1 := NOT 16#7F; |
Tabella 3.6 Operatori booleani
Sono disponibili i seguenti operatori bit-shift, conformi allo standard IEC1131-e:
Tipi di dati ammessi: BYTE
, WORD
, DWORD
, LWORD
.
Simbolo | Descrizione |
---|---|
SHL |
Spostamento a sinistra in senso bit di un operando.r := SHL(in, n); in operando da spostare a sinistra.n numero di bit di cui in viene spostato a sinistra. |
SHR |
Bitwise right-shift di un operandor := SHR(in, n); in operando da spostare a destra.n numero di bit, di cui in viene spostato a destra. |
ROL |
Rotazione bitwise di un operando verso sinistra.r := ROL(in, n); in verrà spostato di una posizione di bit a sinistra n volte mentre il bit più lontano a sinistra verrà reinserito da destra. |
ROR |
Rotazione bitwise di un operando verso destra.r := ROR(in, n); in verrà spostato di una posizione di bit verso destra n volte mentre il bit più lontano a sinistra verrà reinserito da sinistra. |
Tabella 3.7 Operatori bit-shift
Tradotto con DeepL.com (versione gratuita)
Tutte le operazioni di selezione possono essere eseguite anche con le variabili.
Simbolo | Descrizione | Esempio |
---|---|---|
SEL |
Selezione binaria.OUT := SEL(G, IN0, IN1) G determina se IN0 o IN1 è assegnato a OUT . |
Var1 := SEL(TRUE, 3, 4); Il risultato è 4 |
MAX |
Funzione massima.OUT := MAX(IN0, IN1) Restituisce il maggiore dei due valori. |
Var1 := MAX(30, 40); Il risultato è 40 |
MIN |
Funzione Minimum.OUT := MIN(IN0, IN1) Restituisce il minore dei due valori. |
Var1 := MIN(90, 30); Risultato è 30 |
LIMIT |
LimitazioneOUT := LIMIT(Min, IN, Max) |
Var1 := LIMIT(30, 90, 80); Risultato è 80 |
MUX |
MultiplexerOUT := MUX(K, IN0,. ...,INn) |
Var1:=MUX(1, 30, 40, 50); Il risultato è 30 |
Tabella 3.8 Operatori di selezione
Tradotto con DeepL.com (versione gratuita)
Un'espressione è un costrutto che restituisce un valore dopo essere stato valutato. Le espressioni sono composte da operatori e operandi. Un operando può essere una costante, una variabile, una chiamata di funzione o un'altra espressione.
a := b + c;
x := (a - b + c) / 2;
risultato := SIN(a) * COS(b);
L'assegnazione di un valore a una variabile attraverso il risultato di un'espressione o di un valore. L'assegnazione consiste in una variabile sul lato sinistro, che viene designata al risultato di un calcolo sul lato destro dall'operatore di assegnazione :=
. Tutte le assegnazioni devono essere chiuse con un punto e virgola ;
.
a := 10;
b := a;
c := a * 2;
Quando la riga di codice è stata elaborata, il valore della variabile Var1
è doppio rispetto al valore della variabile Var2
.
I commenti vengono talvolta tralasciati, ma sono comunque una componente importante del codice sorgente. Descrivono il codice e lo rendono più facile da leggere. I commenti permettono all'utente o ad altri di leggere facilmente un programma, anche molto tempo dopo che è stato scritto. Non vengono compilati e non hanno alcuna influenza sull'esecuzione del programma. I commenti devono essere inseriti tra una coppia di parentesi e un asterisco (* Commento *)
.
(* questa è una riga di commento *)
(*
questo è
un
multiplo
linea
commento
*)
L'uso di più operatori in una riga solleva la questione della priorità (ordine di esecuzione). L'esecuzione è determinata dalla priorità. Le espressioni vengono eseguite a partire dall'operatore con priorità più alta, seguito dal successivo più alto e così via fino a quando l'espressione non è stata eseguita completamente. Gli operatori con la stessa priorità vengono eseguiti da sinistra a destra, man mano che appaiono nell'espressione.
Operatore | Simbolo - Sintassi | Priorità |
---|---|---|
Parentesi | ( ... ) |
Massima |
Chiamata di funzione | FUCTION(X, Y) |
|
Esponente | ** |
|
Negazione | NOT |
|
Moltiplicazione Divisione Modulo |
* / `MOD`` | |
|
Addizione Sottrazione |
+ - |
|
Confronto | < , > , <= , >= |
|
Uguale a Non uguale a |
= <> |
|
Booleano AND | AND |
|
Booleano XOR | XOR |
|
Booleano OR | OR |
Più basso |
Tabella 3.9 Operatori di confronto
L'ordine di esecuzione in fase di runtime: vedere le immagini seguenti.
a := 6 + 7 * 5 - 3; (* Prima le moltiplicazioni, massima priorità *)
a := 6 + 35 - 3; (* Poi le addizioni, da sinistra a destra *)
a := 41 - 3; (* Sottrazione alla fine *)
a := 38; (* L'assegnazione è l'operazione finale *)
Viene eseguita prima la moltiplicazione, poi l'addizione e infine la sottrazione. L'ordine delle operazioni può essere cambiato mettendo tra parentesi le operazioni a priorità più alta. Questo viene mostrato nell'esempio successivo.
Come mostrato nella figura seguente, l'uso delle parentesi influenza l'esecuzione dell'espressione.
a := (6 + 7) * (5 - 3); (* Prima le parentesi *)
a := 13 * 2; (* Poi le moltiplicazioni *)
a := 26; (* Assegnazione *)
L'espressione viene eseguita da sinistra a destra. Le operazioni tra parentesi vengono eseguite per prime, poi le moltiplicazioni, poiché le parentesi hanno una priorità maggiore. Si può notare che le parentesi portano a un risultato diverso.
L'istruzione IF
viene utilizzata per creare decisioni nel programma.
Gli operatori di confronto sono già noti e possono essere utilizzati anche in questo caso.
Esistono diversi tipi di istruzioni IF.
Decisione | Sintassi | Descrizione |
---|---|---|
IF THEN |
IF (a > b) THEN |
Confronto |
risultato := 1; |
Affermazione/i | |
ELSIF THEN |
ELSIF (a > c) THEN |
Confronto (opzionale) |
risultato : = 2; |
Dichiarazione/i | |
ELSE |
ELSE |
Sopra le dichiarazioni IF non sono TRUE (opzionale) |
`risultato := 3;| Dichiarazione/i | | ||
END_IF |
END_IF |
End if decision |
Tabella 3.10 Struttura di IF
L'istruzione IF
viene testata per ottenere il risultato TRUE
. Se il risultato è FALSE
, il programma avanza alla riga successiva all'istruzione END_IF
. La funzione dell'istruzione IF
può essere un singolo confronto, ma anche più confronti collegati da AND
, OR
, ecc.
IF (a > b) THEN
c := 0;
END_IF;
SE (a > 0) E (b > 0) ALLORA
c := 1;
END_IF;
L'istruzione ELSE
è un'estensione della semplice istruzione IF
. È possibile utilizzare una sola istruzione ELSE
per ogni istruzione IF
.
IF (a > b) THEN (* condizione A *)
c := 0; (* istruzione A *)
ELSE
c := 1; (* istruzione B *)
END_IF;
Se la IF
soddisfa la condizione A, le istruzioni A vengono eseguite. Se la IF
non soddisfa la condizione A, allora vengono eseguite le istruzioni B.
Una o più istruzioni ELSE_IF
consentono di verificare una serie di condizioni senza creare una struttura software confusa con molte semplici istruzioni IF.
IF (a > b) THEN
r := 0;
ELSIF (a > c) THEN
r := 1;
ELSIF (a > d) THEN
r := 2;
ELSE
r := 3;
END_IF;
In fase di esecuzione le decisioni vengono elaborate dall'alto verso il basso. Se il risultato di una decisione è TRUE
, vengono eseguite le istruzioni corrispondenti. Poi il programma continua da dopo la END_IF
. Vengono eseguite solo le decisioni che corrispondono alla prima decisione TRUE
, anche se le decisioni successive sono anch'esse TRUE
. Se nessuna delle decisioni IF
o ELSE_IF
è TRUE
, viene eseguita l'istruzione nel ramo ELSE
.
Un'istruzione IF
annidata viene testata solo se le condizioni precedenti sono state soddisfatte. Ogni IF
richiede il proprio END_IF
in modo che l'ordine delle condizioni sia corretto.
IF (a > b) THEN
IF (c < d) THEN
IF (e = f) THEN
g := 0;
END_IF;
END_IF;
END_IF;
È utile rientrare ogni istruzione IF annidata e le espressioni corrispondenti. È possibile annidare un numero di istruzioni IF pari a quello necessario. È possibile, tuttavia, che il compilatore esaurisca la memoria dopo il 40° livello. Inoltre, questo tipo di annidamento estensivo è indice di un cattivo stile di programmazione. Diventa quasi impossibile avere una visione chiara del codice. Dopo tre livelli di annidamento, è meglio trovare un altro modo per strutturare il programma.
L'istruzione CASE
confronta una variabile di passo con più valori. Se uno di questi confronti corrisponde, vengono eseguiti i passi che si confrontano con quel passo. Se nessuno dei confronti corrisponde, viene eseguito un ramo ELSE simile a un'istruzione IF
. Dopo l'esecuzione delle istruzioni, il programma continua da dopo l'istruzione END_CASE
.
Parole chiave | Sintassi | Descrizione |
---|---|---|
CASE OF |
CASE var OF |
Inizio dell'istruzione CASE |
1: risultato := 1; |
per var = 1 |
|
2, 5: risultato := 1; |
per i valori var = 2 e var = 5 |
|
6. .10 risultato := 1; . .10 risultato := 1; |
per var da 6 a 10 valori |
|
END_CASE |
END_CASE |
Fine dell'istruzione CASE |
Tabella 3.11 Struttura CASE
Per ogni ciclo di programma viene elaborato un solo passo dell'istruzione CASE
.
CASE (a) OF
0:
b := 0;
1..5:
b := 1;
6, 10:
b := 2;
7..9:
b := 3;
AND_CASE;
In molte applicazioni, è necessario che sezioni di codice vengano eseguite più volte durante un ciclo. Questo tipo di elaborazione viene definito anche ciclo. Il codice nel ciclo viene eseguito finché non viene soddisfatta una condizione di terminazione definita.
I loop contribuiscono a rendere i programmi più brevi e facili da seguire. Anche l'espandibilità del programma è un aspetto importante. I loop possono essere annidati.
A seconda della struttura di un programma, è possibile che un errore nel programma faccia sì che l'elaborazione si blocchi ripetendo il ciclo fino a quando il monitor temporale dell'unità centrale non risponde con un errore. Per evitare che si verifichino questi loop infiniti, è quasi sempre necessario includere nella programmazione un modo per interrompere il loop dopo un numero definito di ripetizioni o per eseguirlo fino a un certo limite.
ST
offre diversi tipi di loop tra cui scegliere:
Limitato:
Illimitato:
L'istruzione FOR
viene utilizzata per eseguire una sezione di programma per un numero limitato di ripetizioni. Per tutte le altre applicazioni, si utilizzano i cicli WHILE
o REPEAT
.
Parole chiave | Sintassi | Descrizione |
---|---|---|
FOR TO BY DO |
FOR i := startVal TO endVal {BY stepVal} DO |
Il passo in { } è facoltativo |
(\* fare qualcosa \*) |
Dichiarazione del corpo del loop | |
END_FOR |
END_FOR |
Fine della dichiarazione FOR |
Tabella 3.12 Struttura FOR
Le istruzioni del ciclo FOR
vengono ripetute. A ogni ripetizione, il contatore del ciclo viene incrementato di stepVal
. Le due variabili di controllo startVal
e endVal
determinano il valore iniziale e finale del contatore del ciclo. Una volta raggiunto il valore finale, il programma continua dopo l'istruzione END_FOR
. Le variabili di controllo devono essere entrambe dello stesso Tipo di dati
e non possono essere descritte da nessuna istruzione del corpo del ciclo. L'istruzione FOR
aumenta o diminuisce il contatore del ciclo finché non raggiunge il valore finale. La dimensione del passo è sempre 1, a meno che non sia specificato diversamente con BY
. La condizione di terminazione, il contatore del ciclo, viene valutata a ogni ripetizione del ciclo.
FOR (i := 0) TO 100 BY 2 DO
a := a + 1;
END_FOR;
Il ciclo WHILE
può essere utilizzato allo stesso modo del ciclo FOR
, tranne per il fatto che la condizione può essere una qualsiasi espressione booleana. Se la condizione è soddisfatta, il ciclo viene eseguito. Il ciclo WHILE
viene utilizzato per ripetere le istruzioni finché una particolare condizione rimane TRUE
.
Parole chiave | Sintassi | Descrizione |
---|---|---|
WHILE DO |
WHILE i > endValue DO |
Condizione booleana |
(\* do something \*) |
Istruzione del corpo del ciclo | |
`i := i + 1;| incremento dell'indice | | ||
END_WHILE |
END_WHILE |
Fine della dichiarazione WHILE |
Tabella 3.13 Struttura WHILE
Le istruzioni vengono eseguite ripetutamente finché la condizione restituisce TRUE
. Se la condizione restituisce FALSE
durante la prima valutazione, le istruzioni non vengono mai eseguite.
Se la condizione non assume mai il valore
FALSE
, le istruzioni vengono ripetute all'infinito, causando un errore di esecuzione.
i := 0;
WHILE (i < 10) DO
a := a + 1;
i := i + 1; (* Incremento dell'indice *)
END_WHILE;
Il ciclo REPEAT
si differenzia dal ciclo WHILE
perché la condizione di terminazione viene verificata solo una volta che il ciclo è stato eseguito. Ciò significa che il ciclo viene eseguito almeno una volta, indipendentemente dalla condizione di terminazione.
Parole chiave | Sintassi | Descrizione |
---|---|---|
REPEAT |
REPEAT |
Avvio del ciclo |
(\* do something \*) |
Istruzione del corpo del ciclo | |
i := i + 1; |
incremento dell'indice | |
UNTIL |
UNTIL i < endValue |
Condizione di terminazione |
END_REPEAT |
END_REPEAT |
Fine dell'istruzione REPEAT |
Tabella 3.14 Struttura REPEAT
Le istruzioni vengono eseguite ripetutamente finché la condizione UNTIL
non è TRUE
. Se la condizione UNTIL
è vera fin dall'inizio, le istruzioni vengono eseguite una sola volta.
Se la condizione
UNTIL
non assume mai il valoreTRUE
, le istruzioni vengono ripetute all'infinito, causando un errore di runtime.
i := 0;
REPEAT
a := a + 1;
i := i - 1; (* decremento indice *)
UNTIL (i = 0)
END_REPEAT;
L'istruzione EXIT
può essere utilizzata con tutti i tipi di loop prima che si verifichi la condizione di terminazione.
i := 0;
WHILE (i < 10) DO
IF (a = b) THEN
EXIT;
END_IF;
a := a + 1;
i := i + 1;
END_WHILE;
`````.
# 5. Funzioni
In `ST` una chiamata di funzione può essere usata come operando.
```TS
Risultato := FUNCTION(7) + 3;
Sono disponibili i seguenti operatori numerici IEC, descritti dallo standard IEC 61131-3
Restituisce il valore assoluto di un numero.
L'ingresso e l'uscita possono essere di qualsiasi “tipo di dati” numerici di base.
r := ABS(-2); (* Il risultato in r è 2 *)
Restituisce la radice quadrata di un numero.
La variabile di ingresso può essere un qualsiasi Data Type
di base numerico, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := SQRT(16); (* Il risultato in r è 4 *)
Restituisce il logaritmo naturale di un numero.
La variabile di ingresso può essere un qualsiasi Data Type
numerico di base, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := LN(45); (* Il risultato in r è 3,80666 *)
Restituisce il logaritmo di un numero in base 10.
La variabile di ingresso può essere un qualsiasi tipo di dato
numerico di base, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := LOG(1000); (* Il risultato in r è 3 *)
Operatore numerico IEC: Restituisce la funzione esponenziale.
La variabile di ingresso può essere un qualsiasi Data Type
numerico di base, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := EXP(2); (* Il risultato in r è 7.389056099 *)
Operatore numerico IEC: Esponenziazione di una variabile con un'altra variabile.
La variabile di ingresso può essere un qualsiasi tipo di dati
numerico di base, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := EXPT(7, 2); (* Il risultato di r è 49 *)
Restituisce il seno di un numero. Il valore viene calcolato in minuti d'arco.
La variabile di ingresso può essere un qualsiasi tipo di dati
numerico di base, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := SIN(0.5); (* Il risultato in r è 0.479426 *)
Operatore numerico IEC: Restituisce il coseno di un numero. Il valore viene calcolato in minuti d'arco.
La variabile di ingresso può essere un qualsiasi tipo di dato
numerico di base, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := COS(0,5); (* Il risultato in r è 0,877583 *)
Restituisce la tangente di un numero. Il valore viene calcolato in minuti d'arco.
La variabile di ingresso può essere un qualsiasi tipo di dato
numerico di base, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := TAN(0.5); (* Il risultato in r è 0.546302 *)
Restituisce l'arco di seno (funzione inversa del seno) di un numero. . Il valore è calcolato in minuti d'arco.
La variabile di ingresso può essere un qualsiasi tipo di dati
numerico di base, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := ASIN(0,5); (* Il risultato in r è 0,523599 *)
Restituisce l'arco di coseno (funzione inversa del coseno) di un numero. Il valore è calcolato in minuti d'arco.
La variabile di ingresso può essere un qualsiasi Data Type
numerico di base, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := ACOS(0.5); (* Il risultato in r è 1.0472 *)
Restituisce la tangente all'arco (funzione inversa della tangente) di un numero. Il valore è calcolato in minuti d'arco.
La variabile di ingresso può essere un qualsiasi tipo di dati
numerico di base, mentre la variabile di uscita deve essere di tipo REAL
o LREAL
.
r := ATAN(0.5); (* Il risultato in r è 0.463648 *)
È vietato convertire implicitamente da un tipo grande' a un tipo
piccolo' (ad esempio, da INT' a
BYTE' o da DINT' a
WORD'). Per fare questo sono necessarie conversioni di tipo speciali. In pratica, si può convertire da qualsiasi tipo elementare a qualsiasi altro tipo elementare.
<TIPO1>_A_<TIPO2>
r := BOOL_TO_INT(boolValue);
Si noti che nelle conversioni
<TYPE1>_TO_STRING
la stringa viene generata con il giustificazione a sinistra. Se è definita corta, sarà tagliata dal lato destro.
Operatore IEC: Conversione dal tipo BOOL
a qualsiasi altro tipo.
Sintassi:
BOOL_TO_<TIPO>
Per i tipi numerici il risultato è 1 quando l'operando è TRUE
e 0 quando l'operando è FALSE
.
Per il tipo STRING
il risultato è ‘TRUE’, quando l'operando è TRUE
o ‘FALSE’ quando l'operando è FALSE
.
Operatore IEC: Conversione da un altro tipo di variabile a BOOL
Sintassi:
<TIPO>_A_BOOL
Il risultato è TRUE
quando l'operando non è uguale a 0. Il risultato è FALSE
quando l'operando è uguale a 0.
Il risultato è TRUE
per le variabili di tipo STRING
quando l'operando è ‘TRUE’, altrimenti il risultato è FALSE
.
Conversione da un tipo di numero integrale a un altro tipo di numero. :
Sintassi:
<Tipo di datiINT>_TO_<Tipo di datiINT>
Quando si esegue una conversione da un tipo più grande a uno più piccolo, si rischia di perdere alcune informazioni. Se il numero che si sta convertendo supera il limite dell'intervallo, i primi byte del numero saranno ignorati.
si := INT_TO_SINT(4223); (* Il risultato è 127 *)
Se si salva l'
INTEGER
4223 (16#107f rappresentato esadecimalmente) come variabileSINT
, esso apparirà come 127 (16#7f rappresentato esadecimalmente).
Conversione dal tipo di variabile REAL
o LREAL
a un tipo diverso:
Il valore viene arrotondato per eccesso o per difetto al numero intero più vicino e convertito nel nuovo tipo di variabile. Fanno eccezione i tipi di variabile STRING
, BOOL
, REAL
e LREAL
.
Se un
REAL
oLREAL
viene convertito inSINT
,USINT
,INT
,UINT
,DINT
,UDINT
,LINT
oULINT
e il valore del numero reale è fuori dall'intervallo di valori di quel numero intero, il risultato sarà indefinito e dipenderà dal sistema di destinazione. In questo caso è possibile anche un'eccezione! Per ottenere un codice indipendente dal target, è necessario gestire qualsiasi superamento dell'intervallo da parte dell'applicazione. Se il numero reale/reale rientra nell'intervallo dei valori interi, la conversione funzionerà su tutti i sistemi allo stesso modo.
Quando si esegue una conversione di tipo da un tipo più grande a uno più piccolo, si rischia di perdere alcune informazioni.
i := REAL_TO_INT(1.5); (* Risultato è 2 *)
j := REAL_TO_INT(1.4); (* Risultato è 1 *)
i := REAL_TO_INT(-1.5); (* Risultato è -2 *)
j := REAL_TO_INT(-1.4); (* Risultato è -1 *)
Tradotto con DeepL.com (versione gratuita)
Conversione dal tipo di variabile TIME
o TOD
(Time Of Day) a un tipo diverso.
Sintassi:
<TIPO DI TEMPO>_A_<TIPO>
L'ora verrà memorizzata internamente in una DWORD
in millisecondi (a partire da 12:00 A.M.
per la variabile TOD). Questo valore verrà poi convertito.
Nel caso del tipo STRING, il risultato è una costante di tempo.
Quando si esegue una conversione di tipo da un tipo più grande a uno più piccolo, si rischia di perdere alcune informazioni.
str :=TIME_TO_STRING(T#12ms); (* Il risultato è T#12ms *)
dw := TIME_TO_DWORD(T#5m); (* Il risultato è 300000 *)
si := TOD_TO_SINT(TOD#00:00:00.012); (* Il risultato è 12 *)
Tradotto con DeepL.com (versione gratuita)
Conversione dal tipo di variabile DATE o DATE_AND_TIME a un tipo diverso.
Sintassi:
<TIPO DI DATA>_A_<TIPO>
La data viene memorizzata internamente in una DWORD
in secondi dal 1 gennaio 1970
. Questo valore verrà poi convertito.
Per le variabili di tipo STRING
, il risultato è la costante data.
Quando si esegue una conversione di tipo da un tipo più grande a uno più piccolo, si rischia di perdere alcune informazioni.
b := DATE_TO_BOOL(D#1970-01-01); (* Il risultato è FALSE *)
i := DATE_TO_INT(D#1970-01-15); (* Il risultato è 29952 *)
byt := DT_TO_BYTE(DT#1970-01-15-05:05:05); (* Il risultato è 129 *)
str := DT_TO_STRING(DT#1998-02-13-14:20); (* Il risultato è “DT#1998-02-13-14:20” *)
Tradotto con DeepL.com (versione gratuita)
Conversione dal tipo di variabile STRING
a un tipo diverso.
La conversione funziona secondo il meccanismo di compilazione standard del C: da STRING
a INT
e poi da INT
a BYTE
. Il byte più alto viene tagliato, per cui si ottengono solo i valori 0-255.
Sintassi:
STRING_TO_<TYPE>
L'operando della variabile di tipo STRING
deve contenere un valore valido nel tipo di variabile di destinazione; in caso contrario, il risultato sarà 0.
Quando si esegue una conversione di tipo da un tipo più grande a uno più piccolo, si rischia di perdere alcune informazioni.
b := STRING_TO_BOOL(‘TRUE’); (* Il risultato è TRUE *)
w := STRING_TO_WORD(‘abc34’); (* Il risultato è 0 *)
t := STRING_TO_TIME(‘T#127ms’); (* Il risultato è T#127ms *)
bv := STRING:TO_BYTE(‘500’); (* Il risultato è 244 *)
Conversione da REAL
a DINT
. Verrà utilizzata la porzione di numero intero del valore.
diVar := TRUNC(1.9); (* Il risultato è 1 *)
diVar := TRUNC(-1.4); (* Il risultato è -1 *)
In ST
un blocco funzione è chiamato istanza di blocco funzione e i parametri di trasferimento necessari sono posti tra parentesi.
Operazioni:
Prima di chiamare un blocco funzione, è necessario descrivere le variabili da utilizzare come parametri di ingresso. Il codice per la chiamata di un blocco funzione occupa una riga. Poi si possono leggere le uscite del blocco funzione.
CHECKERROR(errorId := 100, showError := true);
b := CHECKERROR.error;
Prima si inserisce il nome del blocco funzione, poi si assegnano i parametri di trasferimento tra parentesi, separati da virgole. Il codice per chiamare un blocco funzione viene chiuso con un punto e virgola.