robfa_1 Inserito: 26 maggio 2015 Segnala Share Inserito: 26 maggio 2015 Buongiorno a tutti, Devo ricercare un valore(costante) all'interno di un vettore di X elementi. Per il momento , semplificando il problema, facciamo il caso che devo verificare che il valore intero "20" sia presente o no dentro il vettore v[20] , il quale è dichiarato dentro una DB, che chiameremo DB5. Ora, ho visto qualcosa sull'indirizzamento indiretto(LAR , ecc) e i puntatori, ma non riesco ad applicare queste informazioni al mio caso, avrei bisogno di qualche delucidazione in più se possibile. N.B Avrei fatto una funzione in SCL per risolvere questo tipo di problema, ma il mio "superiore" mi ha detto, "ah non iniziamo ad usare l'SCL sennò viene un casino, no per carità". Credo che non sappia dove mettersi le mani con questo linguaggio, mah, comunque lasciamo stare. Meglio che impari ad usare l'indirizzamento indiretto. Grazie a tutti Link al commento Condividi su altri siti More sharing options...
pigroplc Inserita: 26 maggio 2015 Segnala Share Inserita: 26 maggio 2015 Se il tuo capo è così audace mi viene voglia di suggerirti di cambiare azienda ...... L 1 T MD 100 AUF DB5 L DBB[MD100] L 20 ==I S M 0.0 // almeno 1 byte è uguale beb CONT: L MD100 L 1 +I T MD100 L 20 >I BEB SPA CONT buttata giù così senza possibitlità di provare Link al commento Condividi su altri siti More sharing options...
robfa_1 Inserita: 26 maggio 2015 Autore Segnala Share Inserita: 26 maggio 2015 Quindi vediamo se ho capito bene: Inizializzi MD100 a 1, apri la dbX(5 come dicevo nel primo post) e confronti (tipo intero) con il valore 20. se il confronto ha "successo" setti la memoria m0.0 ed interrompe il ciclo con beb(vista ora sulla guida). Altrimenti avanzi al valore successivo del vettore. Quel poco che ho capito è questo. ora vado allo step successivo per il problema "reale" che ho. il vettore di interi si ripete ogni 174 byte a cominciare dal byte 174 della db5 per venti volte, perchè ho 20 venti modelli in quella db. Come devo ragionare in questo caso? Link al commento Condividi su altri siti More sharing options...
pigroplc Inserita: 26 maggio 2015 Segnala Share Inserita: 26 maggio 2015 aggiorni il puntatore e ripeti in un altro segmento invece di fare il BEB fai il salto al segmento successivo Link al commento Condividi su altri siti More sharing options...
batta Inserita: 26 maggio 2015 Segnala Share Inserita: 26 maggio 2015 Occhio che per passare al byte successivo si deve incrementare l'idirizzo (MD100) di 8, e non di 1. Anzi, inizializzare MD100 con valore 1 è un errore, perché l'indirizzo deve esser un multiplo di 8. Io utilizzerei l'istruzione LOOP, con un salto per uscire se si è trovata una corrispondenza. Link al commento Condividi su altri siti More sharing options...
pigroplc Inserita: 26 maggio 2015 Segnala Share Inserita: 26 maggio 2015 Scusa Batta, lo so che sei un virtuoso del codice, ma io mi ricordo che questo è un puntatore semplice e non un registro AR1. Sei sicuro della moltiplicazione per 8 ? (io non posso provare .....) Ciao. Link al commento Condividi su altri siti More sharing options...
batta Inserita: 26 maggio 2015 Segnala Share Inserita: 26 maggio 2015 Sì, sicurissimo. Il funzionamento del puntatore è identico. E va bene così, perché puoi usare lo stesso sistema per puntare al bit. Per esempio, potresti scrivere: U M [MD100] oppure: U DBX [MD100] Codice esempio: FUNCTION FC 7 : VOID TITLE =Cerca valore all'interno di un array VERSION : 0.1 VAR_INPUT NrDB : BLOCK_DB ; NrPrimaVar : INT ; NrVar : INT ; Valore : INT ; END_VAR VAR_OUTPUT Trovato : BOOL ; END_VAR VAR_TEMP adr : DINT ; loopId : INT ; END_VAR BEGIN NETWORK TITLE = //Inizializza "valore trovato" = FALSE SET ; R #Trovato; //Calcola indirizzo prima variabile (1 = prima variabile del DB) L #NrPrimaVar; + -1; SLD 4; T #adr; //Apri DB AUF #NrDB; //Inizio loop L #NrVar; NEXT: T #loopId; //Se il valore è stato trovato, impostare flag "valore trovato" //e uscire dasl loop L DBW [#adr]; L #Valore; ==I ; S #Trovato; SPB EXIT; //altrimenti incrementare indirizzo di una word (16 bit) L #adr; + L#16; T #adr; L #loopId; LOOP NEXT; EXIT: NOP 0; END_FUNCTION Link al commento Condividi su altri siti More sharing options...
pigroplc Inserita: 26 maggio 2015 Segnala Share Inserita: 26 maggio 2015 Batta mi fai venire voglia di riutilizzare l'AWL coi tuoi esempi......ma Simotion non me lo compila Grazie Ciao Link al commento Condividi su altri siti More sharing options...
robfa_1 Inserita: 27 maggio 2015 Autore Segnala Share Inserita: 27 maggio 2015 (modificato) Un grazie entrambi per la disponibilità e la schiettezza con cui spiegate gli aspetti principali di ogni problema che viene posto. Purtroppo alla fine il mio "superiore" ha chiamato il cliente ed ha aggirato il problema, comunque sia questa funzione (quella di batta) la guardo bene e la studio a fondo. [at]Pigroplc la tua risposta riguardo al mio superiore è giusta e il tuo pensiero condivisibilissimo. Io infatti cerco di imparare i metodi giusti dalle persone giuste, non aggirando il problema o chiamando il cliente per cambiare le carte in tavola e farmi "portare" il problema. All'università non sono stato abituato a ragionare così. Comunque non vado oltre sennò diventa una discussione OT. Grazie ancora ad entrambi Modificato: 27 maggio 2015 da robfa_1 Link al commento Condividi su altri siti More sharing options...
JumpMan Inserita: 6 giugno 2015 Segnala Share Inserita: 6 giugno 2015 (modificato) Ciao Batta, mi sono permesso di modificare il tuo codice inserendo l'indirizzamento mediante puntatore AR1, così tanto per far vedere che la differenza è minima (personalmente mi trovo meglio con AR1). Alla fine ho aggiunto un parametro che indica dove ha trovato il valore. ciao a tutti FUNCTION FC 7 : VOID TITLE =Cerca valore all'interno di un array VERSION : 0.1 VAR_INPUT NrDB : BLOCK_DB ; NrPrimaVar : INT ; NrVar : INT ; Valore : INT ; END_VAR VAR_OUTPUT Trovato : BOOL ; Where : INT ; END_VAR VAR_TEMP adr : DINT ; loopId : INT ; END_VAR BEGIN NETWORK TITLE = //Inizializza "valore trovato" = FALSE SET ; R #Trovato; //Calcola indirizzo prima variabile (1 = prima variabile del DB) L #NrPrimaVar; + -1; SLD 4; LAR1 ; //Apri DB AUF #NrDB; //Inizio loop L #NrVar; NEXT: T #loopId; //Se il valore è stato trovato, impostare flag "valore trovato" //e uscire dasl loop L DBW [AR1,P#0.0]; L #Valore; ==I ; S #Trovato; SPB EXIT; //altrimenti incrementare indirizzo di 2 bytes +AR1 P#2.0; L #loopId; LOOP NEXT; L 0; SPA END; EXIT: L #NrVar; L #loopId; -I ; + 1; END: T #Where; END_FUNCTION Modificato: 6 giugno 2015 da JumpMan Link al commento Condividi su altri siti More sharing options...
Messaggi consigliati
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 accountAccedi
Hai già un account? Accedi qui.
Accedi ora