| *Author |
*Topic  |
|
Ivan
Utente Esperto
 
Italia
134 *Posts |
*Posted - 18 Jul 2002 : 16:56:08
Ciao ragazzi, ho un fc con dei parametri in ingresso dichiarati come booleani (32) Vorrei copiarli su una doppia word locale senza fare 32 volte U #N = l0.n Esiste qualche barbatrucco?Grazie *** Messaggio editato da ivan il 19 Jul 2002 09:35:00 *** |
luca.bettinelli
Utente Base

Italia
53 *Posts |
*Posted - 18 Jul 2002 : 18:04:00
L'unica soluzione suppongo sia usare 2 puntatori che ad ogni giro vengono incrementati di 1. Si potrebbe anche al limite usare la funzione di copia di blocchi di memoria tramite un BLKMOVE "SFC20" se le aree di memoria sono contigue (manuale blocchi di sistema).Ciao

|
OscarZ
Nuovo Utente
Italia
10 *Posts |
*Posted - 18 Jul 2002 : 20:43:02
Utilizza queste istruzioniL P#N //Carica indirizzo del primo bit (bool) LAR1 //Pone l'indirizzo caricato nel registro AR1 L D[AR1,P#0.0] //Carica la Dword all'indirizzo AR1 T LD 0 //Trasferisce nella tua Dword di appoggio Spero di esserti stato utile Ciao 
|
il.bassi
Utente Base

Italia
46 *Posts |
*Posted - 18 Jul 2002 : 20:55:03
beh, ti confesso che non posso provarla in questo momento, ma secondo me, se i 32 bit sono contigui, una strada potrebbe essere la seguente:L P##In0 // Carica idirizzo di Ino, con In0 primo bit dei 32 T MD 0 // Puntatore L LD[MD0] // Carica la doppia word contenente i 32 bit contigui T MD 4 // supponendo che la variabile MD4 sia quella dove vuoi // trasferire i 32 bit contigui Se hai modo di provarla, fammi sapere se funziona! purtroppo, io sono momentaneamente senza CPU... Ciao da Andrea  
|
walterword
Utente Base

Italia
38 *Posts |
*Posted - 18 Jul 2002 : 22:37:39
ciao ivan scusa un attimo da quello che scrivi tu carichi una local bool con 'L' al posto di 'U', dopodiche la assegni ad un ingresso (I0.n)??? se cosi non fosse dovresti vedere se quello che passi all'fc sia contiguo nel senso e0.0...e3.7 o merker o dbx ecc in modo tale da poterlo configurare come array[0..31] of bool . L'area sopra la quale dovrai copiare sara pure un'array che dichiarerai tu nella tendina delle dichiarazioni su temp come [N , bool,array[0..31] of bool] A questo punto come dice il.bassi dovrai usare due cicli-loop annidati, l'esterno servira' per "SPOLPARE" i byte da 0 a 3 (per ex.) , il ciclo interno invece "SPOLPA" i bit da 0 a 7. quando finisce di contare 7 incrementa il byte di 1. e' una specie di sfc20 fatta in casa in base ad esigenze particolari se pero magari potresti essere un po piu chiaro potrei sicuramente dirti qualcosa in piu ciao

|
OscarZ
Nuovo Utente
Italia
10 *Posts |
*Posted - 18 Jul 2002 : 23:13:03
Il metodo di "il.bassi" non dovrebbe funzionare perché se non si utilizza il registro di indirizzo (AR1) diventa impossibile accedere all'area temporanea del blocco dati chiamante (chiamata V da qualche parte nei manuali). Il trucco consiste nel fatto che la chiamata di una fc: CALL fc1 i1: I0.0 i2: M0.1 ecc. corrisponde all'incirca a queste istruzioni: A I0.0 = L0.0 A M0.1 = L0.1 LAR2 p#L0.0 UC fc1 cioè il blocco dati chiamante copia tutti i parametri da inviare alla fc nella sua area temporanea e passa alla fc l'indirizzo iniziale di quest'area. Se i 32 bool sono parametri contigui (non è necessario che siano contigui gli indirizzi dei parametri) questi vengono copiati in modo contiguo, quindi possono essere recuperati facilmente col metodo che ho descritto in precedenza. P.S.: Sono abbastanza convinto che la cosa funzioni, tuttavia posso verificarla solo domani, fatemi sapere!Ciao a tutti

|
il.bassi
Utente Base

Italia
46 *Posts |
*Posted - 19 Jul 2002 : 09:12:53
Ciao, sono riuscito a provare il tutto: effettivamente ha ragione Oscar, bisogna passare attraverso il registro AR1; la mia soluzione invece non funziona.Pensavo che l'istruzione L P##In0 caricasse un puntatore "area-crossing", cioè contenente l'informazione dell'indirizzo assoluto del byte del parametro In0, e il tipo di area di memoria, cioè quella dei dati locali. Credo che il problema sia nel fatto che, all'interno della FC, l'indirizzo di inizio dell'area dei dati locali viene spostato subito dopo i parametri locali della funzione. Sarebbe necessario, come dice Oscar, riuscire a indirizzare l'area dei parametri locali (area V): quest'area però non è direttamente accessibile (o almeno io non ci sono riuscito) a meno di non passare per il registro AR1. Ciao a tutti da Andrea  
|
Ivan
Utente Esperto
 
Italia
134 *Posts |
*Posted - 19 Jul 2002 : 09:40:29
Dunque ho fatto un po' di prove ma non ho risolto. Il metodo di OscarZ (a parte che quando scrivi L#N lui automaticamente mette L##N) punta al parametro passato, cioè se io come primo parametro metteo M50,0 lui mi carica nella LD0 i MB 50,51,52 e 53 Faro altre prove ed accetto altri consigli.*** Messaggio editato da ivan il 19 Jul 2002 16:11:16 *** |
OscarZ
Nuovo Utente
Italia
10 *Posts |
*Posted - 19 Jul 2002 : 13:37:58
In mattinata ho fatto delle prove e devo fare qualche precisazione. Quello che ho detto riguardo ai richiami delle fc vale effettivamente per gli fb, dove i parametri vengono copiati in modo contiguo nel db di istanza (ovvio). Il metodo che ho descritto funziona perfettamente a patto pero` che gli indirizzi dei "bool" siano contigui, come dice "walterword". Il vantaggio ulteriore che ne consegue utilizzando questo metodo e` che si puo` passare alla funzione soltanto il primo "bool" (gli altri vengono recuperati automaticamente), si ha cosi` un risparmio notevole di memoria e di velocita` di esecuzione! P.S.: l'istruzione L P#N in effetti sta per L P##N Il discorso riguardo all'accesso dell'area V diventa utile in altre situazioni... ad esempio se volessi caricare qualche variabile temporanea degli OB, dove il sistema pone dei dati che possono risultare utili. P.P.S.: dalle prove che ho effettuato non penso che si possa utilizzare alcun barbatrucco se gli indirizzi non sono contigui, poiche` non esiste alcuna istruzione del PLC che mi permetta di indirizzare l'area dove vengono memorizzati i puntatori ai parametri delle fc. Se si utilizzano tipi di dati composti questi indirizzi vengono effettivamente memorizzati nell'area V, ma col tipo di dati "bool" essi spariscono letteralmente. Ho provato a sostituire "bool" con "pointer" nella dichiarazione della fc, in questo caso tutto il discorso dell'area V diventa valido, ma si ha uno spreco di memoria ingiustificato.
|
Ivan
Utente Esperto
 
Italia
134 *Posts |
*Posted - 19 Jul 2002 : 16:05:36
Ok lasciamo stare, copio a manina. Potresti spiegare il discorso dell' area v che sui manuali non ho trovato nulla?
Come la indirizzi? Cosa contiene? ecc... 
|
OscarZ
Nuovo Utente
Italia
10 *Posts |
*Posted - 19 Jul 2002 : 17:54:56
In effetti sui manuali l'area V è solo accennata. In sostanza essa non è altro che l'area L (temporanea) del blocco (ob, fc , fb) che ha chiamato la fc o l'fb che stai programmando. Considera per esempio che l'ob1 ha una variabile temporanea che si chiama OB_SCAN_TIME (vado a memoria) indirizzata in LW20 (non mi ricordo l'indirizzo esatto ma basta guardare nella tabella dell'ob1); in questa word c'è il tempo di scansione del PLC espresso in ms, può tornarmi utile ad esempio se voglio contare il tempo di qualche processo (se incremento una DBW o una DBD con questo tempo ottengo praticamente un orologio). Se creo una fc che ha bisogno di questa variabile la devo passere come parametro di ingresso, ma questo può rivelarsi una scocciatura per l'utilizzatore della funzione oltre che una perdita di tempo e di memoria del PLC (infatti il passaggio dei parametri nei richiami dei blocchi è molto dispendioso in termini di prestazioni in s7). Se metto come vincolo che la fc possa essere richiamata solo nell'ob1, posso leggere la suddetta variabile direttamente dalla fc in modo del tutto trasparente per l'utilizzatore. Naturalmente ci sarebbero molte altre possibilità di utilizzo dell'area V, ma normalmente non si ha la necessità di ricorrere all'utilizzo di tecniche simili di programmazione.Ma tornando a noi, mi togli una curiosità: come ti torna utile il fatto di raccogliere tutti i bool in una LD? Magari ci sono altre soluzioni... 
|
walterword
Utente Base

Italia
38 *Posts |
*Posted - 19 Jul 2002 : 19:38:41
ciao ivan ,a la "manina" per caso ti si e' incantata? ciao
|
Ivan
Utente Esperto
 
Italia
134 *Posts |
*Posted - 22 Jul 2002 : 08:32:51
Per Walterword cosa intendi per "manina incantata" se c'e un modo per fare una cosa con una o due righe di istruzione, perche farlo in 70?OscarZ grazie per la delucidazione, ma fammi ancora una cortesia spiegami come si fa ad utilizzarle nel fc le variabili V. Il discorso di copiare molti bool su una Ld mi serve perchè ho un software scritto da altri in cui ho molte stazioni di una macchina i cui stati sono scritti in bit uguali di Byte diversi (m1.0,m2.0,m3.0 ecc..) e a me serve sapere se tuute le stazioni hanno la stessa condizione. 
|
walterword
Utente Base

Italia
38 *Posts |
*Posted - 22 Jul 2002 : 21:11:01
intendevo che probabilmente ti si era incantata quando spedivi le risposte al forum , ne hai scritte una cifra tutte uguali cosa avevi capito ? ahahahah ciao ivan

|
Ivan
Utente Esperto
 
Italia
134 *Posts |
*Posted - 23 Jul 2002 : 08:00:54
Oh, non ho notato i post doppi Il problema e' che ogni tanto il forum non mi funziona a dovere (messaggi tipo "script time error" e robette del genere) probabilmente era una di quelle volte. 
|
OscarZ
Nuovo Utente
Italia
10 *Posts |
*Posted - 23 Jul 2002 : 10:52:35
I registri AR1 e AR2 contengono in 32 bit l'indirizzo e l'area di memoria da indirizzare, l'area di memoria si trova nel byte piu` significativo (puoi trovare spiegazioni sulla guida online): se poni il valore B#16#87 nel byte piu` significativo di AR1 (o AR2), questi puntano all'area V (cioe` alle variabili temporanee del blocco che ha richiamato la fc). Attenzione pero` che i registri ARx si possono utilizzare in due modi: come registri interni od esterni all'area di memoria (se li utilizzo come interni il byte di codifica dell'area di memoria viene ignorato). Per farti un esempio l'istruzione L MW[AR1,p#0.0] punta sempre all'area Merker indipendentemente da quanto specificato in AR1 (viene considerato solo l'indirizzo). Se voglio utilizzare l'area di memoria specificata in AR1 devo scrivere cosi`: L W[AR1,p#0.0]Per leggere gli stessi bit in byte consecutivi puoi agire cosi`: LAR1 P#0.0 //Azzera AR1 LAR2 P#0.0 //Azzera AR2 L x //Al posto di x poni il numero delle stazioni Lop: A M[AR1,p#0,y] //Al posto di y poni l'indirizzo del bit (l'istruzione va a leggere nell'area Merker) = L[AR2,p#z.0] //Al posto di z poni l'ind.del byte dell'area L (locale) dove vuoi memorizzare i bit in modo consecutivo +AR1 P#1.0 //Incrementa AR1 di un Byte +AR2 P#0.1 //Incrementa AR2 di un Bit LOOP Lop //Cicla per il numero di stazioni P.S.: Se devi solo fare un And dei bits puoi cancellare tutte le istruzioni che riguardano AR2, subito dopo l'istruzione LOOP trovi nell'RLC il risultato della serie di And di tutti i bit: basta che poni ad esempio un'istruzione come = L0.0 Spero di esserti stato utile Ciao 
|
Ivan
Utente Esperto
 
Italia
134 *Posts |
*Posted - 23 Jul 2002 : 13:32:18
Grazie, mi sei stato molto utile. Ora leggo un po' e facio prove, in caso ci risentiamo.

|
walterword
Utente Base

Italia
38 *Posts |
*Posted - 23 Jul 2002 : 18:11:57
allora alla fine ci vogliono due loop e duie puntatori....
|