Vai al contenuto
PLC Forum


Indirizzare Un Array In Una Fb


montese

Messaggi consigliati

Salve a tutti,

oggi mi stavo cimentando nelle FB con DB di istanza.

Uno schema semplificato di quello che volevo realizzare è questo:

Un FB a cui passo i valori A e B, esegue C=A+B, con C parametro in uscita.

Inoltre Il DB di istanza contiene anche una array di 10x3 elementi e la FB memorizza nell'array i valori A,B e C incrementando un indice che ogni volta segna il posto.

Il problema è che non riesco ad assegnare i valori A,B e C nell'array con l'istruzione:

T DBD [AR1, P#0.0]

Quando arriva qui, il simulatore da errore.

Essendo la prima volta che uso i DB, forse ho sbagliato nel dichiarare le variabili.

Ho messo A,B,C in "IN" e l'array in "STAT".

Se copio il codice fuori dalla FB non ho nessun errore.

Link al commento
Condividi su altri siti


Con l'istruzione

T DBD [AR1, P#0.0]

scrivi il contenuto dell'accumulatore in una DWORD del DB globale attualmente aperto, e non del DB di istanza.

L'istruzione da usare è:

T DID [AR1, P#0.0]

Oppure, se il registro indirizzi contiene già l'informazione dell'area di memoria (B#16#85 per DB di istanza), basta indicare solo il formato della variabile:

T D [AR1, P#0.0]

Dimenticavo di dire che, per questo tipo di operazioni, tutto risulta più facile usando l'SCL.

Modificato: da batta
Link al commento
Condividi su altri siti

Grazie infinite Batta!

Avoglia a impazzirmi a controllare il calcolo di AR1 etc etc...

Non capisco però la terza ipotesi. (T D [AR1, P#0.0])

Potresti farmi un esempio pratico?

Modificato: da montese
Link al commento
Condividi su altri siti

Dipende da come hai caricato l'indirizzo in AR1.

Supponiamo tu abbia l'array "MioArray" [0..10] of Struct, dove la struttura è formata da una variabile INT, una variabiel DINT e una variabile REAL.

Se scrivi:

L P##MioArray

vedrai che nell'accumulatore viene caricato un valore che, in esadecimale, inizia con 85.

Questo 85 esadecimale sta ad indicare che l'area di memoria è di un DB di istanza.

Quindi, se scrivi:

LAR1 P##MioArray

nel registro indirizzi 1 viene caricato l'indirizzo di partenza dell'array, e anche l'area di memoria.

In questo caso non serve specificare che vuoi accedere al dato di un DB di istanza, perché che si tratta di un DB di istanza è già specificato nell'indirizzo.

Devi quindi specificare solo il formato della variabile (nell'esempio si tratta di una DWORD, indicata dalla lettera D). Puoi quindi scrivere semplicemente:

T D [AR1, P#0.0]

Scrivere

T DID [AR1, P#0.0]

non è comunque sbagliato.

O meglio, non è sbagliato in questo caso, dove vuoi accedere esclusivamente al DB di istanza.

In casi più articolati, dove l'accesso potrebbe essere fatto ad aree di memoria diverse (specificate nell'indirizzo), aggiungendo quel "DI" andresti a forzare l'accesso al DB di istanza, ignorando l'informazione eventualmente contenuta nell'indirizzo.

Se, invece, carichi l'indirizzo facendo dei calcoli ma non specifichi l'area di memoria, ti troverai un indirizzo incompleto.

In questo caso, specificare l'area di memoria scrivendo

T DID [AR1, P#0.0]

diventa obbligatorio.

Per continuare l'esempio con questo array (formato da 10 strutture con una variabile da 2 byte e due variabili da 4 byte), caricando l'indirizzo con l'istruzione

LAR1 P##MioArray

puoi accedere alla prima variabile della della prima struttura dell'array scrivendo:

T W[AR1, P#0.0]

alla seconda variabile con:

T D[AR1, P#2.0]

e alla terza co:

T D[AR1, P#6.0]

Per accedere alle strutture successive dell'array, dovrai incrementare AR1 di 10 byte per ogni indice dell'array.

Il calcolo dell'indirizzo dell'inizio di ogni struttura potrebbe quindi essere fatto come segue:

	  LAR1  P##MioArray				 //Carica indirizzo inizio array

	  L	 P#10.0					  //Carica dimensione struttura (10 byte)

	  L	 #ID						 //Carica indice array (allineato a zero)

	  *D								//Calcola offset indirizzo struttura puntata da ID

	  +AR1							  //Incrementa AR1 con offset calcolato
Dopo aver calcolato l'indirizzo di inizio della struttura dell'array puntata da "ID", puoi assegnare i valori alle variabili scrivendo:
	  L	 Valore_INT

	  T	 W [AR1,P#0.0]

	  L	 Valore_DINT

	  T	 D [AR1,P#2.0]

	  L	 Valore_REAL

	  T	 D [AR1,P#6.0]
In SCL invece, potresti semplicemente scrivere:
	MioArray[ID].VarInt := .... ;

	MioArray[ID].VarDint := .... ;

	MioArray[ID].VarReal := .... ;

In SCL il codice è molto più intuitivo. Il rovescio della medaglia è che, quasi sempre, una funzione scritta in SCL occupa più memoria (e questo implica anche più lavoro per il processore) di una analoga scritta in AWL.

Per prova, ho scritto due funzioni, una in AWL ed una in SCL, per scrivere un valore nelle variabili dell'array dell'esempio, indicando l'indice "ID".

La dimensione della funzione in AWL è risultata di 84 byte, mentre quella della funzione in SCL è di 204 byte.

Link al commento
Condividi su altri siti

Batta, un 10 e lode per la chiarezza e la disponibilità!

Mi hai chiarito cose di cui ancora non ancora immaginavo l'esistenza :)

E io che pensavo che sui DB non c'era molto da sapere... Non pensavo nemmeno che la memoria dell'S7 fosse così articolata.

Ho fatto programmi che occupavano tutta la memoria principale (quella delle merker per intenderci) senza usare una DB!

Mi piacerebbe avere a disposizione l'SCL, ma purtroppo ho solo una vecchia versione di step7. Sarebbe tutto più facile visto che tanto tempo fa programmavo in pascal.

Grazie ancora, metterò in pratica tutto al più presto.

Massimo.

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...