globulo73 Inserito: 8 ottobre 2008 Segnala Inserito: 8 ottobre 2008 Ciao a tutti,vorrei implementare un programmino in AWL che conti gli uni (livelli alti) di una word magari un codice compatto e ciclico!!!!grazie sin da ora per la collaborazione
Livio Orsini Inserita: 8 ottobre 2008 Segnala Inserita: 8 ottobre 2008 Semplice usa l'istruzione shift (a dx o a sx non ha importanza) incrementando un contatore con il bit overflow == 1FAi un loop di 16 volte e testi tutta la word
globulo73 Inserita: 8 ottobre 2008 Autore Segnala Inserita: 8 ottobre 2008 grazie per il suggerimento anche se non mi è chiaro come "legare" in AWL le 3 strutture:SHIFT, CONTATORE, LOOPquesto sicuramente dovuto alla mia scarsa conoscenza del linguaggio AWL.Inoltre il bit di overflow appartiene alla parola di stato?
globulo73 Inserita: 8 ottobre 2008 Autore Segnala Inserita: 8 ottobre 2008 Provo di seguito ad inquadrare la cosa senza rispettare tanto la sintassi AWL (gli indirizzi degli operandi sono puramente a scopo didattico): L 16 //numero cicliNEXT: T MB0 //merker di conteggio cicli L MW7 //word da testare SLW L BitOverflow //interrogazione bit di over flow che non ho capito quale sia e come funziona ==1 //verifico il bit SPBN fine //se BitOverflow diverso da 1 salto a etichetta fine cosi non incremento Z5 ZV Z5 fine: LOOP NEXT L Z5 T MW11 //word dove appoggio il valore degli uni conteggiatiforse sono fuori strada quindi apprezzerei molto un aiuto!!!
batta Inserita: 8 ottobre 2008 Segnala Inserita: 8 ottobre 2008 Vedi se ti va bene QUESTOLa funzione ti permette di contare i bit alti di un'area dati.Per contare i bit alti di una variabile a 16 bit (2 byte) puoi passare in ingresso l'indirizzo della variabile e 2 come lunghezza.Per una variabile da 4 byte imposti 4 come lunghezza.Se invece non ti interessa la possibilità di contare i bit alti di un'area lunga a piacere, un codice più essenziale potrebbe essere il seguente://Inizializzo conteggio a zero L 0 T "NrBitOn" //Appoggio variabile da controllare a variabile locale L "MiaVar" T #AuxVar //Inizio routine conteggio bit alti M000: L 0 L #AuxVar ==I //Se il valore è ZERO significa che non ci sono bit alti, quindi //esco senza perdere tempo ad effettuare altri controlli SPB END //altrimenti, effettuo uno shift a destra di un bit //ed aggiorno la variabile locale M001: SRW 1 T #AuxVar //L'operazione "T" non modifica i bit di stato, mentre l'operazione "SRW" //assegna al bit di stato "A1" il valore dell'ultimo bit shiftato. //Con l'istruzione "SPZ" testo quindi lo stato dell'ultimo bit shiftato. //Se lo stato di questo bit era ZERO, non incremento il conteggio ed effettuo subito //un altro shift. Evito anche di rifare la comparazione per testare se nella variabile //ci sono ancora bit alti: avendo eliminato un bit basso, se c'erano prima bit alti, //sicuramente ce ne saranno ancora. SPZ M001 //Se il bit shiftato era alto, incremento il conteggio e torno a controllare se //la variabile contiene ancora bit alti. L "NrBitOn" + 1 T "NrBitOn" SPA M000 END: NOP 0Rispetto alla soluzione con loop, ha il piccolo vantaggio di non eseguire più controlli quando tutti i bit della variabile sono bassi e di effettuare qualche operazione in meno.
globulo73 Inserita: 8 ottobre 2008 Autore Segnala Inserita: 8 ottobre 2008 grazie batta per le diverse soluzioni implementate!!!!!ma come faccio ad aprire o importare il file BitCnt.AWL????????
Livio Orsini Inserita: 8 ottobre 2008 Segnala Inserita: 8 ottobre 2008 Rispetto alla soluzione con loop, ha il piccolo vantaggio di non eseguire più controlli quando tutti i bit della variabile sono bassi e di effettuare qualche operazione in meno.Dipende se ci sono più zeri o più uni. Nel caso di maggioranza di zeri è sicuramente più veloce, mentre lo è meno se la maggioranza dei bits è a uno.
globulo73 Inserita: 8 ottobre 2008 Autore Segnala Inserita: 8 ottobre 2008 Ciao Livio, in base alla soluzione che mi prospettavi:SHIFT, CONTATORE, LOOP ecc...(che ho provato ad "abbozzare") è possibile avere un esempio dimostrativo in AWL?grazie per la disponibilità
batta Inserita: 8 ottobre 2008 Segnala Inserita: 8 ottobre 2008 Dipende se ci sono più zeri o più uni. Nel caso di maggioranza di zeri è sicuramente più veloce, mentre lo è meno se la maggioranza dei bits è a uno.Sono differenze di poco conto, e quasi nessuno ormai si preoccupa più della velocità di esecuzione di una subroutine.Ma il sistema con loop può essere al massimo (caso di tutti i bit alti) veloce uguale, mai più veloce.Per fare un confronto più diretto tralascio le istruzioni iniziali (uguali) e scrivo, senza commenti, solo le istruzioni per il conteggio dei bit alti.Metodo con controllo valore variabile:M000: L 0 L #AuxVar ==I SPB END M001: SRW 1 T #AuxVar SPZ M001 L "NrBitOn" + 1 T "NrBitOn" SPA M000 END: NOP 0 L'elenco delle operazioni è il seguente: 1) carica valore 2) carica valore 3) confronto 4) salto condizionato 5) shift a sinistra di un bit (solo se ci sono ancora bit alti) 6) trasferisci valore (solo se ci sono ancora bit alti) 7) salto condizionato (solo se ci sono ancora bit alti) 8) carica valore (solo con bit alto) 9) incremento (solo con bit alto) 10) trasferisci valore (solo con bit alto) 11) salto incondizionato (solo con bit alto) Non considero il passo non operativo finale, perché eseguito una sola volta Metodo con loop: L 16 NEXT: T "IdLoop" L #AuxVar SRW 1 T #AuxVar SPZ M000 L "NrBitOn" + 1 T "NrBitOn" M000: L "IdLoop" LOOP NEXTL'elenco delle operazioni è il seguente:Tralasciamo il caricamento del valore 16, che avviene una sola volta1) trasferisci valore2) carica valore3) shift a sinistra di un bit4) trasferisci valore5) salto condizionato6) carica valore (solo con bit alto)7) incremento (solo con bit alto)8) trasferisci valore (solo con bit alto)9) carica valore10) istruzione LOOPApparentemente una istruzione in meno, con il loop. Ma se scomponiamo l'istruzione LOOP nelle reali operazioni per il processore, queste diventano decremento e salto condizionato.Le istruzioni per il processore sono quindi praticamente le stesse, nei due metodi, quando i bit sono alti, mentre col mio metodo vengono saltate operazioni quando i bit sono bassi.Inoltre, col mio metodo, quando viene shiftato uno zero, viene poi eseguita solo un'operazione di trasferimento ed un salto condizionato.Col metodo del loop invece, shiftando uno zero vengono saltate solo le istruzioni per l'incremento del conteggio, ma vengono sempre eseguite quelle relative alla gestione del loop.Sono comunque entrambi metodi corretti, e non ha molto senso discutere su quale sia il migliore. Io ho voluto proporre il mio solo per presentare qualcosa di diverso, che esce un po' dai soliti schemi.
batta Inserita: 8 ottobre 2008 Segnala Inserita: 8 ottobre 2008 ma come faccio ad aprire o importare il file BitCnt.AWL????????Il file "BitCnt.zip" contiene "BitCnt.awl".Seleziona la cartella "Sorgenti" del tuo progetto --> Pulsante destro --> Inserisci nuovo oggetto --> Sorgente esternaPoi devi compilare il file sorgente così importato.
globulo73 Inserita: 9 ottobre 2008 Autore Segnala Inserita: 9 ottobre 2008 sempre esaurienti!!!!!grazie e buon lavoro
Livio Orsini Inserita: 9 ottobre 2008 Segnala Inserita: 9 ottobre 2008 Sono comunque entrambi metodi corretti, e non ha molto senso discutere su quale sia il migliore. Io ho voluto proporre il mio solo per presentare qualcosa di diverso, che esce un po' dai soliti schemi.Sono completamente d'accordo con queste affermazioni.Ho l'impressione che la sub con il loop possa essere ottimizzata ulteriormente, però non programmando S7 e PLC in genere da almeno cinque anni, mi rimetto a chi lo usa quotidianamente . Volendo essere pignoli la comparazione andrebbe fatta sul tempo impiegato dalla CPU per eseguire le istruzioni e non sul numero di istruzioni. Ma questi sono sofismi inutili.La ricerca di soluzioni alternative è sempre un'ottima cosa, se non altro impone sempre e comunque un ragionamento ed impedisce la fossilizzazione su soluzioni note.
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