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




Conteggio Livelli Alti (uni) Presenti In Una Word


Messaggi consigliati

Inserito:

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


Inserita:

Semplice usa l'istruzione shift (a dx o a sx non ha importanza) incrementando un contatore con il bit overflow == 1

FAi un loop di 16 volte e testi tutta la word

Inserita:

grazie per il suggerimento anche se non mi è chiaro come "legare" in AWL le 3 strutture:SHIFT, CONTATORE, LOOP

questo sicuramente dovuto alla mia scarsa conoscenza del linguaggio AWL.

Inoltre il bit di overflow appartiene alla parola di stato?

Inserita:

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 cicli

NEXT: 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 conteggiati

forse sono fuori strada quindi apprezzerei molto un aiuto!!!

Inserita:

Vedi se ti va bene QUESTO

La 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   0

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.

Inserita:

grazie batta per le diverse soluzioni implementate!!!!!

ma come faccio ad aprire o importare il file BitCnt.AWL????????

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

Inserita:

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à

Inserita:
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  NEXT

L'elenco delle operazioni è il seguente:

Tralasciamo il caricamento del valore 16, che avviene una sola volta

1) trasferisci valore

2) carica valore

3) shift a sinistra di un bit

4) trasferisci valore

5) salto condizionato

6) carica valore (solo con bit alto)

7) incremento (solo con bit alto)

8) trasferisci valore (solo con bit alto)

9) carica valore

10) istruzione LOOP

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

Inserita:
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 esterna

Poi devi compilare il file sorgente così importato.

Inserita:

sempre esaurienti!!!!!

grazie e buon lavoro

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

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