Vai al contenuto
PLC Forum


Indirizzamento Indiretto


mattidentity

Messaggi consigliati

salve a tutti

mi trovo davanti a quello che per i più esperti è un banalissimo problema a scopo didattico.

Devo sommare i numeri interi all'interno di un array usando i puntatori. Ora, girando nelle vecchie discussioni ho trovato

parecchio materiale ma vorrei alcuni piccoli chiarimenti.

Praticamente in un DB ho creato un array di interi (array[1..25]), ho impostato i valori all'interno della tabella "dati" e ora voglio sommarli.

Ho trovato questo sul forum:

LOOP: L #_indice_Array

+ -1

L L#2

*D

SLD 3

LAR1

AUF DB10

L DBW [AR1,P#0.0]

L #_indice_Array

+ 1

T #_indice_Array

L 10

<=I

SPB LOOP

ma precisamente non capisco:

1 - nella voce #_indice array che dati devo mettere

2 - il passaggio + - 1

Link al commento
Condividi su altri siti


1 - nella voce #_indice array che dati devo mettere

Prima di entrare nelk loop, nella variabile #_indice array devbi caricare il numero della prima variabile.

Attenzione che non è l'indirizzo della variabile in byte, ma il numero della variabile partendo da 1.

Esempio: se vuoi iniziare i calcoli dalla prima variabile del DB (DB10.DBW0), devi impostare 1; se vuoi iniziare i calcoli dalla variabile DB10.DBW10, dovrai impostare 6.

2 - il passaggio + - 1

Questo serve per correggere l'indice della variabile, dato che si è scelto di impostare l'indice della variabile partendo da 1 e non da 0.

Il codice però non può funzionare, perché le variabili puntate da #_indice array vengono solo lette. Manca la somma dei valori delle variabili.

Inoltre sarebbe migliorabile. Non ha molto senso infatti moltiplicare l'indice per due e poi fare uno shift a sinistra di 3 bit, basta fare uno shift a sinistra di 4 bit.

Link al commento
Condividi su altri siti

Buongiorno a tutti,

ho corretto la parte dello shift ed ho inserito gli indici DB ma non credo di aver compilato correttamente

il programmino.

Nella prima parte punto alla prima locazione del Db.

Il codice però non può funzionare, perché le variabili puntate da #_indice array vengono solo lette

Ma questo incremento non ce l'ho della seconda parte dove c'è " L +1".

Io avevo interpretato la cosa come un incremento di 1 del puntatore.

Grazie

Link al commento
Condividi su altri siti

Praticamente in un DB ho creato un array di interi (array[1..25]), ho impostato i valori all'interno della tabella "dati" e ora voglio sommarli.

Da qui io capisco che tu voglia calcolare la somma di tutte le 25 variabili del tuo array.

Ma questo incremento non ce l'ho della seconda parte dove c'è " L +1".

Nel primo codice incrementi solo il puntatore, ma il valore della variabile puntata lo leggi e basta.

Nel codice del post #4, fai ancora più pasticci, perché:

- hai eliminato l'indice della variabile da leggere. Ora leggerai sempre e solo il valore della variabile DB1.DBW0.

- non uscirai mai dal loop, perché con le istruzioni

L 1

+ 1

T DB1.DBW0

andrai a scrivere in DB1.DBW0 sempre l valore 2.

La comparazione quindi sarà sempre vera (2 <= 15), e continuerai a saltare indietro fino a quando la cpu andrà in stop per il superamento del tempo massimo di ciclo (watchdog).

Se, al posto dell'istruzione + 1 metti +I, allora partendo con DB1.DBW0 = 0 farai solo il primo ciclo completo di incrementi, e questi incrementi riguarderanno solo DB1.DBW0, e nessun'altra variabile del tuo array.

Dopo la prima volta, incrementerai DB1.DBW0 di una unità, perché l'incremento viene fatto indipendentemente dal valore di DB1.DBW0, ma uscirà subito dal loop perché la comparazione DB1.DBW0 <= 15 sarà sempre falsa.

Se spieghi quello che hai intenzione di fare, posso buttare giù un esempio.

Link al commento
Condividi su altri siti

allora quello che ho intenzione di fare è la somma di tutti i numeri che sono presenti all'interno della tabella dati

Se prendiamo come riferimento l'immagine postata prima, vorrei fare una semplicissima

operazione di somma tra interi presenti nell'array.

ES: 12+20+3+31+15+13 e cosi via...

Il totale sarà un intero (somma di tutti gli interi dell'array).

Grazie ancora

Link al commento
Condividi su altri siti

Ho creato DB10 con un array di 20 variabili INT (da DB10.DBW0 a DB10.DBW38) e una variabile DB10.DBD40 di tipo DINT per contenere la somma.

Ho buttato giù due piccoli esempi, testati col simulatore.

Esempio 1:

	  L	 0						   //Inizializza indice (0 = prima variabile del DB)

	  T	 #id


	  L	 L#0						 //Inizializza variabile temporanea somma

	  T	 #TmpSum


	  AUF   "DB_Dati"				   //Apri DB


NEXT: L	 #id						 //Carica indice

	  ITD							   //Trasforma da INT a DINT

	  SLD   4						   //Shift a sx di 4 bit per variabili da 16 bit

	  LAR1							  //Carica l'indirizzo calcolato in AR1

	  L	 #TmpSum					 //Carica valore somma temporanea

	  L	 DBW [AR1,P#0.0]			 //Carica valore della variabile puntata

	  ITD							   //Converti da INT a DINT

	  +D								//Somma

	  T	 #TmpSum					 //Scrivi risultato in somma temporanea


	  L	 #id						 //Carica indice

	  +	 1						   //Incrementa

	  T	 #id

	  L	 19						  //Controlla se raggiunto indice finale

	  <=I  

	  SPB   NEXT


	  L	 #TmpSum					 //Carica valore attuale somma

	  T	 "DB_Dati".Somma			 //e scrivilo in variabile globale
Esempio 2:
	  L	 0						   //Inizializza indice

	  T	 #id


	  L	 L#0						 //Inizializza variabile temporanea somma

	  T	 #TmpSum


	  AUF   "DB_Dati"				   //Apri DB


	  LAR1  P#DBX 0.0				   //Inizializza AR1 con indirizzo prima variabile


M000: L	 #TmpSum					 //Carica valore somma temporanea

	  L	 DBW [AR1,P#0.0]			 //Carica valore della variabile puntata

	  ITD							   //Converti da INT a DINT

	  +D								//Somma

	  T	 #TmpSum					 //Scrivi risultato in somma temporanea


	  L	 #id						 //Carica indice

	  +	 1						   //Incrementa

	  T	 #id

	  L	 19						  //Controlla se raggiunto indice finale

	  >I	

	  SPB   EXIT


	  L	 P#2.0					   //Incrementa AR1 di due byte

	  +AR1  

	  SPB   M000


EXIT: L	 #TmpSum

	  T	 "DB_Dati".Somma
Tra i due, quello che preferisco è il secondo, perché ti permette di caricare l'indirizzo della prima variabile da sommare e il numero di variabili in modo indipendente. In questo modo, se la prima variabile fosse la DB10.DBW50, ti basterebbe caricare in AR1 l'indirizzo P#DBX50.0 Nel primo esempio invece, se volessi sommare sempre 20 variabili a partire da DB10.DBW50, dovresti inizializzare l'indice id = 25, e terminare il loop quando id > 44. Molto meno intuitivo. Se lo fai in SCL, diventa tutto ancora più semplice. Esempio:
FUNCTION FC2 : VOID


VAR_TEMP

	SumTmp: DINT;

	id:	 INT;

END_VAR


//Inizializza somma temporanea

	SumTmp := 0;

//Somma 20 variabili dell'array "VarArray[0..19] of int"

	FOR id := 0 TO 19 DO

		SumTmp := SumTmp + INT_TO_DINT("DB_Dati".VarArray[id]);

	END_FOR;


	"DB_Dati".Somma := SumTmp;


END_FUNCTION

Link al commento
Condividi su altri siti

Grazie mille per l'esempio,

sto cercando di provarlo ma non ci sono ancora riuscito dato che

quando vado a compilarlo non metto bene i valori su

T #id

T #TmpSum

L #id

Ho creato nella tabella degli array un indirizzo (l'ultimo) DINT (DB1.DBD30) e l'ho chiamato "somma".

Questo valore lo vado a sostituire nell'ultima riga (ES.2) dove c'è scritto T (DB_Dati.Somma) e credo sia giusto.

Ma allora su T #TmpSum che variabile devo mettere?

Grazie ancora e scusami se sono un po testone

Link al commento
Condividi su altri siti

id è una variabile temporanea di tipo INT

TmpSum è una variabile temporanea di tipo DINT.

Le variabili temporanee sono quelle che dichiari, all'interno della funzione, nell'interfaccia delle variabili (quella in alto).

Ho creato nella tabella degli array un indirizzo (l'ultimo) DINT (DB1.DBD30) e l'ho chiamato "somma".

Ma DB1 è lo stesso DB che contiene l'array della variabili da sommare? Se è così, non può avere indirizzo DBW30, perché un array di 20 variabili di tipo INT che parte da DBW0 arriva fino a DBW38.

L'indirizzo disponibile immediatamente successivo è il byte 40, quindi la variabile "somma" deve essere DB1.DBD40.

Era già tutto scritto nella prima riga del mio post #7.

Una domanda: se non sai come si dichiarino le variabili TEMP, mi viene da pensare che, con i plc Siemens, tu stia muovendo i primi passi. Se è così, non credi che dovresti dedicarti a qualcosa di più semplice dei puntatori?

Link al commento
Condividi su altri siti

Ma DB1 è lo stesso DB che contiene l'array della variabili da sommare? Se è così, non può avere indirizzo DBW30, perché un array di 20 variabili di tipo INT che parte da DBW0 arriva fino a DBW38

Il mio DB1 è formato da un array con 15 elementi INT. Poi ne ho creato un altro e quindi l'indirizzo disponibile successivo è il DB1.DBD30

Come hai ben capito, sono ai primi passi ma mi è stato chiesto di studiare i puntatori. Devo imparare in fretta!

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...