UR65 Inserito: 19 ottobre 2014 Segnala Share Inserito: 19 ottobre 2014 buongiorno a tutti, ho la necessità di comandare un'uscita con l'intervento di uno qualunque dei tanti bit di una db. per evitare che uno imposti a 0 e l'altro a 1, e fare fallire il comando, ho pensato di interrogare il fronte di salita. mi chiedevo: esiste un comando o un blocco che controlla tutti i bit di una data area di byte? questo per evitare di scrivere un'istruzione lunga sia a bit che a word. grazie per l'aiuto. buona domenica! ma rispondetemi Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 19 ottobre 2014 Segnala Share Inserita: 19 ottobre 2014 Come l'hai impostata la domanda non è chiara. Comunque se ti limiti a settare o resettare l'uscita in funzione dello stato dei bits l'uscita prenderà lo stato dell'ultimo bit testato; questo avverrà solo alla fine del ciclo quando la tabella immagine viene copiata sulle uscite fisiche. Se invece vuoi che l'uscita vada alta se anche uno solo dei bits interessati sia alto, alla fine del ciclo di programma fai un or tra i vari bits ed al primo "1" alzi l'uscita. Link al commento Condividi su altri siti More sharing options...
dan64100 Inserita: 19 ottobre 2014 Segnala Share Inserita: 19 ottobre 2014 Ciao, se non ho capito male vuoi sapere se, data una DB, almeno uno dei suoi bit è alto. Io ho scritto tempo fa questa FC, lavora su un'intera DB (che gli passi come parametro), in output hai un booleano (FOUND) che ti dice se almeno un bit è alto e un intero (INDEX) che ti dice quale bit è alto. Adattamenti: Se ti interessa lavorare con un area di memoria arbitraria devi modificare il parametro d'ingresso DATA facendolo diventare ANY ed estraendo all'interno dell'FC il numero della DB, start e la lunghezza. Se non ti interessa conoscere l'indice del bit puoi cancellare il segmento 2 (tranne la label e le istruzioni SET e = #FOUND) e il segmento 3. FUNCTION "TEST_ZERO" : VOID TITLE = //Cerca il primo Bit alto in una DB //IN // DATA : DB sorgente //OUT // FOUND : True se esiste un bit alto, False se la DB è tutta a zero // INDEX : Indice del primo bit alto // NOTA: // Primo bit DBX0.0 -> Indice=1 // Secondo bit DBX0.1 -> Indice=2 ecc.. // Se FOUND=FALSE -> INDEX=0 AUTHOR : Nardella FAMILY : UTILS NAME : Z_TEST VERSION : 0.1 VAR_INPUT DATA : BLOCK_DB ; //DB Sorgente END_VAR VAR_OUTPUT FOUND : BOOL ; //=True se esiste un bit a 1 INDEX : INT ; //Indice del bit alto (primo bit=1) END_VAR VAR_TEMP AUX_LOOP : INT ; BIT_IDX : INT ; BYTE_IDX : INT ; AUX_BYTE : BYTE ; END_VAR BEGIN NETWORK TITLE = //Ricerca del primo Byte <> 0 // Calcolo lunghezza DB OPN #DATA; L DBLG; T #AUX_LOOP; // Azzeramento indici L 0; T #BYTE_IDX; T #BIT_IDX; // Setup puntatore e contatore loop L P#DBX 0.0; LAR1 ; L #AUX_LOOP; LOOP: T #AUX_LOOP; // Test Byte L B [AR1,P#0.0]; T #AUX_BYTE; L 0; <>I ; JC FND; // Incremento puntatore e indice byte +AR1 P#1.0; L #BYTE_IDX; L 1; +I ; T #BYTE_IDX; // test and loop L #AUX_LOOP; LOOP LOOP; // Nessun Byte <>0 L 0; T #INDEX; CLR ; = #FOUND; JU END; NETWORK TITLE = //Ricerca del bit all'interno del byte FND: SET ; = #FOUND; L #AUX_BYTE; L W#16#1; AW ; JZ BIT1; L 1; T #BIT_IDX; JU CALC; BIT1: L #AUX_BYTE; L W#16#2; AW ; JZ BIT2; L 2; T #BIT_IDX; JU CALC; BIT2: L #AUX_BYTE; L W#16#4; AW ; JZ BIT3; L 3; T #BIT_IDX; JU CALC; BIT3: L #AUX_BYTE; L W#16#8; AW ; JZ BIT4; L 4; T #BIT_IDX; JU CALC; BIT4: L #AUX_BYTE; L W#16#10; AW ; JZ BIT5; L 5; T #BIT_IDX; JU CALC; BIT5: L #AUX_BYTE; L W#16#20; AW ; JZ BIT6; L 6; T #BIT_IDX; JU CALC; BIT6: L #AUX_BYTE; L W#16#40; AW ; JZ BIT7; L 7; T #BIT_IDX; JU CALC; BIT7: L 8; T #BIT_IDX; NETWORK TITLE =Calcolo indice CALC: L #BYTE_IDX; SLD 3; L #BIT_IDX; +I ; T #INDEX; NETWORK TITLE =ENO END: SET ; SAVE ; END_FUNCTION Buona domenica anche a te Davide Link al commento Condividi su altri siti More sharing options...
walterword Inserita: 19 ottobre 2014 Segnala Share Inserita: 19 ottobre 2014 (modificato) se i bit che attivano l'uscita che ti interessa sono contigui puoi valutare se la o le word in questione sono maggiori di zero . Se invece i bit sono sparpagliati a caso in giro per il DB allora li metti in OR logico Modificato: 19 ottobre 2014 da walterword Link al commento Condividi su altri siti More sharing options...
UR65 Inserita: 20 ottobre 2014 Autore Segnala Share Inserita: 20 ottobre 2014 grazie, molto gentili, soprattutto perché ieri era domenica........ comunque risolverò con sicurezza grazie alle vostre indicazioni e visto che i bits sono contigui e non ho necessità di individuare il bit in particolare, farò come mi ha indicato Walterword. grazie a tutti Link al commento Condividi su altri siti More sharing options...
walterword Inserita: 20 ottobre 2014 Segnala Share Inserita: 20 ottobre 2014 per correttezza , devi valutare se la o le words sono diverse da zero , non uguali .....il discorso del bit di segno ect ect .... dan.....in scl due righe Link al commento Condividi su altri siti More sharing options...
dan64100 Inserita: 20 ottobre 2014 Segnala Share Inserita: 20 ottobre 2014 dan.....in scl due righe e levarmi il gusto di giocherellare con AR1 ??? Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 20 ottobre 2014 Segnala Share Inserita: 20 ottobre 2014 devi valutare se la o le words sono diverse da zero , non uguali ... Walter avevi già scritto: valutare se la o le word in questione sono maggiori di zero . Se sono maggiori di 0 sono anche diverse da zero e levarmi il gusto di giocherellare con AR1 A volte è divertente, è come programmare in assembler; però quando devi produrre..... Link al commento Condividi su altri siti More sharing options...
JumpMan Inserita: 20 ottobre 2014 Segnala Share Inserita: 20 ottobre 2014 Non ho esaminato bene l'esempio di Dan, ma credo faccia più di quello che serve... Essendo io passato per S5 tendo sempre a inserire il minimo di istruzioni possibile, se dovessi p.es. esaminare una DB con 256 bit (immagino siano gli allarmi) per vedere se almeno uno è TRUE farei così: L DBD 0 L DBD 4 OD L DBD 8 OD L DBD 12 OD L DBD 16 OD L DBD 20 OD L DBD 24 OD L DBD 28 OD L L#0 <>D = "PresenzaAllarme" Poi ovvio che se devo fare un FC/FB flessibile parametrizzato e adattabile a qualsiasi DB non farei così, ci sono 1000 modi di fare la stessa cosa... Link al commento Condividi su altri siti More sharing options...
dan64100 Inserita: 20 ottobre 2014 Segnala Share Inserita: 20 ottobre 2014 (modificato) Le DB erano di dimensioni variabili, alcune di 4k, motivo per cui non ho usato SCL. Ed era importante conoscere l'indice, altrimenti il codice si dimezza. Modificato: 20 ottobre 2014 da dan64100 Link al commento Condividi su altri siti More sharing options...
JumpMan Inserita: 20 ottobre 2014 Segnala Share Inserita: 20 ottobre 2014 Lavorando a doppia word anzichè a byte ne esce un codice molto snello: SET R #xTemp1 // Azzera bool locale L #NrDB // Nr DB da aprire T #wTemp1 AUF DB [#wTemp1] // Apre la DB L #PrimaDBW // Nr prima DBW SLW 3 LAR1 // imposta puntatore L #QtaDBW // Quantità DBW L1: T #iCtr // imposta contatore loops L DBD [AR1,P#0.0] L L#0 <>D // Se trovato DBW <> 0 S #xTemp1 // setta bit temp +AR1 P#4.0 L #iCtr LOOP L1 U #xTemp1 = #Found Richiamo in OB1: CALL FC 1 NrDB :=2 PrimaDBW:=0 QtaDBW :=8 Found :=M10.0 Link al commento Condividi su altri siti More sharing options...
walterword Inserita: 20 ottobre 2014 Segnala Share Inserita: 20 ottobre 2014 Livio , te se un piugiat Link al commento Condividi su altri siti More sharing options...
UR65 Inserita: 21 ottobre 2014 Autore Segnala Share Inserita: 21 ottobre 2014 salve a tutti, ho provato il suggerimento di Walter e naturalmente ha funzionato bene. proverò quella di Jump.......veramente snella. grazie saluti! Link al commento Condividi su altri siti More sharing options...
JumpMan Inserita: 21 ottobre 2014 Segnala Share Inserita: 21 ottobre 2014 Per snellire ancor di più l'esecuzione puoi uscire dal loop appena trovi un bit: SET R #xTemp1 // Azzera bool locale L #NrDB // Nr DB da aprire T #wTemp1 AUF DB [#wTemp1] // Apre la DB L #PrimaDBW // Nr prima DBW SLW 3 LAR1 // imposta puntatore L #QtaDBW // Quantità DBW L1: T #iCtr // imposta contatore loops L DBD [AR1,P#0.0] L L#0 <>D // Se trovato DBW <> 0 S #xTemp1 // setta bit temp SPB end /// ---> end +AR1 P#4.0 L #iCtr LOOP L1 end: U #xTemp1 = #Found Alla fine questo codice devo dire che risulta molto simile a quello di dan64100 (ripulito della parte che calcola l'indice del bit) solo che lavorando a doppia-word il plc esegue meno istruzioni. Link al commento Condividi su altri siti More sharing options...
dan64100 Inserita: 21 ottobre 2014 Segnala Share Inserita: 21 ottobre 2014 La soluzione della DoubleWord è senz'altro quella più veloce soprattutto se serve solo sapere se è tutto zero o meno. Per un utilizzo generico però bisogna fare attenzione che che tutto sia allineato a DBD (o meglio che l'area da analizzare sia multipla di 4). Link al commento Condividi su altri siti More sharing options...
walterword Inserita: 21 ottobre 2014 Segnala Share Inserita: 21 ottobre 2014 dan , io sono ignorante e molto limitato .Faccio sempre fatica a capire cosa vogliono o cosa devo fare . Per questo che sono sempre cosi sintetico 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