Vai al contenuto
PLC Forum


Puntare E Copiare Udt Da Un Db


antoniaz

Messaggi consigliati

Ciao a tutti :smile:

Vado a spiegare il mio problema.

Ho un DB (es. DB100) contenete un certo numero (N) di UDT (es. UDT100) tutti dello stesso tipo.

Ho una FB che tra i parametri in ingresso prevede un ingresso di tipo UDT100.

Sto scrivendo una FC che mi permetta di eseguire N volte l'FB passando ogni volta come parametro d'ingresso l'ennesimo UDT corrispondente contenuto in DB100.

All'interno dell'FC non riesco a capire come indicizzare e passare l'UDT all'FB.

Per fare chiarezza, se l'ingresso dell'FB fosse un dato di tipo Word o DWord e DB100 contenesse non udt ma tutti dati di tipo Word o DWord saprei risolvere il problema con il puntatore. Purtroppo non mi risulta possibile poter puntare un intero UDT per copiarlo in una variabile temporanea e passarlo poi all'FB.

Chiedo a voi un parere in merito a questo problema. :worthy:

Spero di essere stato sufficentemente chiaro.

un Saluto Loris

Link al commento
Condividi su altri siti


Ciao,

me lo chiedo e mi rispondo.....o meglio l' . ON STATMENT LIST risponde....cercando CONTENTS e poi l 'argomento EXAMPLE OF DATA TYPE ANY...

sembra darmi un buono spunto per risolvere la questione.

Ora provo ad istruirmi un pò :smile:

Altri consigli son sempre bene accetti!

Modificato: da antoniaz
Link al commento
Condividi su altri siti

io di solito lo faccio coi puntatori...

dovresti calcolarti il puntatore che punta all'inizio del primo udt poi sapendo la dimensione puoi spostare il puntatore di n byte.

cosi poi fai un loop per n cicli quanti sono gli udt spostandoti di n byte.

per non mettere numeri fissi ti crei un db con solo un udt del tipo che ti serve usare.. la dimensione di questo sarà sempre uguale alla dimensione del tuo udt. quindi n byte

questo ti permette se un domani allunghi l'udt i dati si indicizzano in dinamico..

non so se mi son spiegato.

Link al commento
Condividi su altri siti

Ti ringrazio pkk

avevo provato a fare qualcosa di simile.

Poi ho approfondito l'ANY PPOINTER e combinando questo con SFC20 BLOKMOV, sposto direttamente l'UDT sorgente nella variabile UDT da passare alla funzione FB.

Sicuramente la tua soluzione ha un vantaggio in termini di carico computazionale rispetto alla mia, ma questo aspetto non è problematico per ora.

Grazie ancora

Link al commento
Condividi su altri siti

Buona sera.

Mi intrometo anche io in questa discussione:

Ho un problema per certi versi similare al tuo antoniaz:

Tento di esporlo chiaramente.

Ho un FB, richiamanto nell'OB1, con un suo DB d'istanza. L'FB è composto da alcune UDT.

Ad esempio: FB100, DB di istanza 100.

La dichiarazione delle variabili dell'FB è composta da

In ...

Out...

STAT: UDT1,

UDT2,

UDT3

...

altri FB, bool etc etc.

Le UDT(X) sono composte dalle seguenti variabili:

variabile tipo

Indice int

a bool

a bool

a bool

a bool

....

svarati altri dati bool, fino ad arrivare a 10 word.

Mi trovo, una volta siddisfatte alcune determinate condizioni, a dover azzerare delle word di una determinata UDT.

Il numero delle word da azzerare (che è sempre consecutivo ovvero se devo azzerare 1a word azzero la prima. Se ne azzero 2 assera la 1a e la 2a e così via) è dipendente dallo stato di condizioni dei bit nella statica dell'FB100.

Per fare ciò ho creato una funzione, (FC) che ho inserito all'interno e alla fine dellFB.

Ora entriamo nella struttura dell'FC:

in ingresso ci ho messo:

il primo bit della UDT che devo azzerare, in formato pointer

un indice intero che contiene il numero di word che devo azzerare.

e questo è il codice che ho provato ad elaborare.

TAR1 #AR1_Tmp //salva il contenuto dei registri

TAR2 #AR2_Tmp

//**************************************

// FUNCTION che Scrive ZERO in una VARIABILE a WORD

// contenuta in un FB Multistanza

L P##FirstBit // Legge l'indirizzo P#

LAR1 // della VARIABILE in ingresso

TAR2 // Carica l'indirizzo nel registro 1 AR1

+AR1

TAR1 #Pointer_1st_Bit

L 1 // controllo su contatore

L #N_Word // inizializza contatore

<I

SPBB cyWD // se contatore <=0 alloraRes

// resetta solo 1a word

L 0 // reset della word

T W [AR1,P#0.0]

SPA END

L #N_Word

cyWD: T #I

LAR1 #Pointer_1st_Bit

L 0 // carico 0 in accumulatore

T W [AR1,P#0.0] // metto a zero l indirizzo puntato

+AR1 P#2.0 //incremento puntatore di 1 word

TAR1 #Pointer_1st_Bit

L #I

LOOP cyWD

LAR1 #AR1_Tmp

LAR2 #AR2_Tmp //ripristino dei registri

END: NOP 0

//*****************************

//***************************************

LAR1 #AR1_Tmp //Ripristina il contenuto dei registri

LAR2 #AR2_Tmp

Ho provato aon una CPU 300, il risultato è che negli accumulatori, mi ritrovo l'indirizzo non del db100.dbx 4.0 (che dovrebbe essere 85000040), ma bensì 87000050, che trasferito in AR1 mi da V10.0, che la guida recota essere: "Area precedente dei dati locali, per l'accesso ai dati locali del blocco richiamante".

Dove sbaglio?

E' sbagliato usare i puntatori all'interno di un FC?

O è sbagliato farlo solo se lo inserisco all'interno di un FB che contiene le stesse aree che voglio puntare?

Grazie!

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