Vai al contenuto
PLC Forum

Partecipa anche tu alla Live su Youtube martedì 28/01/2025 per festeggiare i 24 anni di PLC Forum

Per ulteriori informazioni leggi questa discussione: https://www.plcforum.it/f/topic/326513-28012025




Block_mov: Problema Con Parametro In_out


Messaggi consigliati

Inserito:

Ciao a tutti,

ho un FC a cui passo un tipo UDT come IN_OUT parameter. Ad un certo punto del suddetto FC, dovrei copiare un dato STRING dal suddetto tipo UDT ad un'altro dato STRING di un DB. Purtroppo pero', quando cerco di passare il dato STRING del parametro tipo UDT alla BLOCK_MOV, mi da il seguente errore:

"l'area di dichiarazione della pagina attuale VAR_IN_OUT non è compatibile con l'area di dichiarazione formale VAR_INPUT del parametro formale SRCBLK"

Il codice è il seguente:

CALL "BLOCK_MOV"

SRCBLK := #COILTAB.COIL.COILID // passato com IN_OUT

RET_VAL:=#tmpint

DSTBLK :="Track".COILID

C'è qualche modo per evitare tutto ciò ? Ci sono alternative per copiare stringhe ?

Grazie a tutti per l'aiuto !!!!!


Inserita:

In questo momento non ho sottomano il PG, ma mi sembra che il parametro SRCBLK della "BLOCK_MOV"

deve essere di tipo ANY, quindi incompatibile con STRING!

Ciao

Inserita:

quindi come posso fare ? :blink:

Ogni aiuto è bene accetto, sto impazzendo !

Inserita:

I parametri srcblk e dstblk non accettano array del tipo dati STRING.

Inserita:

Se ho capito bene il problema è quello di spostare una stringa di n byte da un DB ad un altro, giusto?

Inserita:

Non so se usare "BLOCK_MOV" sia conveniente, forse esiste una FC IEC già fatta per fare queste cose. In ogni modo per poter utilizzare BLOCK_MOVE devi specificare nell'area di origine e di destinazione dei dati, dei parametri/puntatori ANY che contengono informazione sul punto d'inizio dell'area e la quantità di dati espressa in byte. Es. P#DB10.DBX0.0 BYTE 12 = dodici byte a partire dal primo bit di DB10.

Inserita:

Devi anche fare attenzione che quando muovi stringhe ti devi preoccupare di scrivere/aggiornare i primi due byte relativi alla lunghezza della stringa. Guardati bene come sono formati ANY e STRING nell'. di S7!

Ciao

Inserita:

Poi trasferire direttamente da una area ad un'altra.

L DBx.DBDy

t DBx1.DBDy1

tante volte quanti sono i dati da trasferire. Per snellire il programma puoi anche aprire simultaneamente le 2 DB e trasferire dirttamente i dati:

AUF DI1

AUF DI2

L DBD 0

T DID 0

......

......

Ultima soluzione fare un loop con una indicizzazione e trasferire tutti i dati con lo stesso sistema ma indicizzando il byte(o word o dword) di lettura o scrittura)

Inserita:

Il problema è che il DB sorgente è un parametro IN_OUT di tipo UDT. Come posso indirizzare tal parametro ?

Inserita:

Guardando meglio mi sono accorto che BLOCK_MOVE accetta anche stringhe, non ti funzionava perchè probabilmente usavi una string come parametro formale d'ingresso in una FC, questo non si può fare!

Ciao

Inserita: (modificato)
Il problema è che il DB sorgente è un parametro IN_OUT di tipo UDT. Come posso indirizzare tal parametro ?

è propio quello che dicevo!

Quando il parametro è IN o IN_OUT è soltanto un puntatore alla stringa da cui puoi ricavare l'indirizzo della stringa, per poi andare a comporre il puntatore ANY da passare alla BLOCK_MOVE!

Ciao

Modificato: da elsabz
Inserita:

Forse abuso della tua gentilezza, ma non avresti un piccolo esempio su come trasformare il parametro in tipo ANY ?

Grazie mille in anticipo.

Inserita: (modificato)
Forse abuso della tua gentilezza, ma non avresti un piccolo esempio su come trasformare il parametro in tipo ANY ?

Abusare della mi gentilezza? Non è tanto quello il problema ma sarebbe meglio che tu comprendessi le cose usando il tuo cervello e sfruttando i manuali che si trovano sul sito SIEMENS. Comunque per stavolta ho qualcosa già fatto e te lo posto nella speranza che questo possa essere d'aiuto anche ad altri.

Importantissimo è capire come è strutturato un puntatore POINTER e ANY

POINTER

post-133061-1378467287,4136_thumb.jpg

ANY

post-133061-1378467315,2779_thumb.jpg

Utilizza l'. in linea S7 e usa POINTER e ANY per trovare la descrizione di questi formati!

Nella FC devi avere i seguenti parametri:

IN_OUT

STRINGA1 String[...]

(Quando richiami questa FC il parametro lo indichi come desideravi: per es. #COILTAB.COIL.COILID

TEMP

Sorgente ANY (indirizzo 0.0) TASSATIVO!

Destinazione ANY (indirizzo 10.0) TASSATIVO!

app1 INT

stringa_lung BYTE

Numero_DB WORD

Questo è il codice della FC

//Carica l'indirizzo del dato formale
      L     P##STRINGA1
      LAR1  

//Ricava il numero di DB
      L     W [AR1,P#0.0]
      T     #Numero_DB

//Ricava l'indirizzo assoluto della stringa
      L     D [AR1,P#2.0]
      LAR1  

//Ricava la lunghezza massima della stringa
      AUF   DB [#Numero_DB]
      L     DBB [AR1,P#0.0]

//Carica nuovamente l'indirizzo del dato formale
      L     P##STRINGA1
      LAR1  

//Composizione puntatore ANY DB sorgente
//Sorgente inizia dai DATI LOCALI "L 0.0" !
      L     B#16#10                     //10h per S7
      T     LB     0
      L     B#16#2                      //Tipo di dati BYTE
      T     LB     1
      L     #stringa_lung               //Fattore di ripetizione=lunghezza stringa +
      +     2                           //i due byte ausiliari della stringa stessa
      T     LW     2
      L     #Numero_DB                  //Numero della DB
      T     LW     4
      L     D [AR1,P#2.0]               //Indirizzo
      T     LD     6

//Composizione puntatore ANY DB destinazione
//Destinazione inizia dai DATI LOCALI "L 10.0" !
      L     W#16#10                     //10h per S7
      T     LB    10
      L     2                           //Tipo di dati BYTE
      T     LB    11
      L     #stringa_lung               //Fattore di ripetizione=lunghezza stringa +
      +     2                           //i due byte ausiliari della stringa stessa
      T     LW    12
      L     1                           //Numero della DB (Per esempio DB1)
      T     LW    14
      L     B#16#84                     //Indirizzo - area blocco dati
      T     LB    16
      L     0                           //Indirizzo byte.bit - (Per esempio dal byte 0)
      T     LB    17
      T     LW    18

//Richiamo funzione copia di dati
      CALL  "BLKMOV"
       SRCBLK :=#Sorgente
       RET_VAL:=app1
       DSTBLK :=#Destinazione

Puoi addattare il tuo indirizzo di destinazione modificando quello che carichi e trasferisci in LB 17 e 18, facendo attenzione che questo è un puntatore byte,bit come POINTER!

Ciao

Sergio

Modificato: da elsabz
Inserita: (modificato)

Nel codice precedente da me postato c'è un piccolo errore!

Guardate il seguente che è corretto:

//Carica l'indirizzo del dato formale
      L     P##STRINGA1
      LAR1  

//Ricava il numero di DB
      L     W [AR1,P#0.0]
      T     #Numero_DB

//Ricava l'indirizzo assoluto della stringa
      L     D [AR1,P#2.0]
      LAR1  

//Ricava la lunghezza massima della stringa
      AUF   DB [#Numero_DB]
      L     DBB [AR1,P#0.0]
      T     #stringa_lung   

//Carica nuovamente l'indirizzo del dato formale
      L     P##STRINGA1
      LAR1  

//Composizione puntatore ANY DB sorgente
//Sorgente inizia dai DATI LOCALI "L 0.0" !
      L     B#16#10                     //10h per S7
      T     LB     0
      L     B#16#2                      //Tipo di dati BYTE
      T     LB     1
      L     #stringa_lung               //Fattore di ripetizione=lunghezza stringa +
      +     2                           //i due byte ausiliari della stringa stessa
      T     LW     2
      L     #Numero_DB                  //Numero della DB
      T     LW     4
      L     D [AR1,P#2.0]               //Indirizzo
      T     LD     6

//Composizione puntatore ANY DB destinazione
//Destinazione inizia dai DATI LOCALI "L 10.0" !
      L     W#16#10                     //10h per S7
      T     LB    10
      L     2                           //Tipo di dati BYTE
      T     LB    11
      L     #stringa_lung               //Fattore di ripetizione=lunghezza stringa +
      +     2                           //i due byte ausiliari della stringa stessa
      T     LW    12
      L     1                           //Numero della DB (Per esempio DB1)
      T     LW    14
      L     B#16#84                     //Indirizzo - area blocco dati
      T     LB    16
      L     0                           //Indirizzo byte.bit - (Per esempio dal byte 0)
      T     LB    17
      T     LW    18

//Richiamo funzione copia di dati
      CALL  "BLKMOV"
       SRCBLK :=#Sorgente
       RET_VAL:=app1
       DSTBLK :=#Destinazione

Modificato: da elsabz
Inserita: (modificato)

Ciao a tutti,

ho elaborato una nuova e migliore versione del codice precedentemente da me postato.

Questa versione non necessita di avere l'indirizzo fisso predeterminato, per i parametri "Sorgente" e "Destinazione" dei dati TEMP. In questo modo si evita di commettere eventuali errori d'indirizzamento.

In oltre ho sostituito i parametri TEMP "Numero_DB" e "stringa_lung" sempre con dati locali ma indirizzati direttamente (LW100 e LW102) ed ho aggiunto LD104 per salvare AR2. Queste ultime modifiche le ho dovute fare per il motivo che utilizzando AR2 bisogna sempre stare attenti, in quanto la CPU utilizza AR2 per determinare l'indirizzo dei parametri formali. Indirizzando direttamente l'area dei dati locali sono più sicuro di non fare errori, anche se bisogna prestare ancora attenzione a non sovrapporre questi registri con altri parametri dei dati locali (fino a 100 sono tutti liberi!)

Il codice è il seguente:

//LW 100 = Numero_DB
//LW 102 = stringa_lung
//LD 104 = appoggio salvataggio AR2

//Salva AR2
      TAR2  
      T     LD   104

//Carica l'indirizzo del dato formale
      L     P##STRINGA1
      LAR1  

//Ricava il numero di DB
      L     W [AR1,P#0.0]
      T     LW   100

//Ricava l'indirizzo assoluto della stringa
      L     D [AR1,P#2.0]
      LAR1  

//Ricava la lunghezza massima della stringa
      AUF   DB [LW 100]
      L     DBB [AR1,P#0.0]
      T     LW   102

//Carica nuovamente l'indirizzo del dato formale
      L     P##STRINGA1
      LAR1  

//Carica AR2 con il valore del puntatore relativo al parametro #Sorgente
      L     P##Sorgente
      LAR2  

//Composizione puntatore ANY DB sorgente
      L     B#16#10                     //10h per S7
      T     LB [AR2,P#0.0]
      L     B#16#2                      //Tipo di dati BYTE
      T     LB [AR2,P#1.0]
      L     LW   102                    //Fattore di ripetizione=lunghezza stringa +
      +     2                           //i due byte ausiliari della stringa stessa
      T     LW [AR2,P#2.0]
      L     LW   100                    //Numero della DB
      T     LW [AR2,P#4.0]
      L     D [AR1,P#2.0]               //Indirizzo
      T     LD [AR2,P#6.0]

//Ripristina AR2
      L     LD   104
      LAR2  
//Carica AR2 con il valore del puntatore relativo al parametro #Destinazione
      L     P##Destinazione
      LAR2  

//Composizione puntatore ANY DB destinazione
      L     W#16#10                     //10h per S7
      T     LB [AR2,P#0.0]
      L     2                           //Tipo di dati BYTE
      T     LB [AR2,P#1.0]
      L     LW   102                    //Fattore di ripetizione=lunghezza stringa +
      +     2                           //i due byte ausiliari della stringa stessa
      T     LW [AR2,P#2.0]
      L     1                           //Numero della DB (Per esempio DB1)
      T     LW [AR2,P#4.0]
      L     B#16#84                     //Indirizzo - area blocco dati
      T     LB [AR2,P#6.0]
      L     0                           //Indirizzo byte.bit - (Per esempio dal byte 0)
      T     LB [AR2,P#7.0]
      T     LW [AR2,P#8.0]

//Ripristina AR2
      L     LD   104
      LAR2  

//Richiamo funzione copia di dati
      CALL  "BLKMOV"
       SRCBLK :=#Sorgente
       RET_VAL:=#app1
       DSTBLK :=#Destinazione

Ciao

Sergio

Modificato: da elsabz

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