Vai al contenuto
PLC Forum


Verifica Bit All'interno Di Una Stringa


yupanqui

Messaggi consigliati

Salve ragazzi,

Cerco una qualche funzione che mi permetta di vedere quale bit si trova ad uno all'interno di una word o ancora meglio all'interno di una data area di memoria.

Prima utilizzavo i plc della ge e li c'e' una funzione nominata bitpos che mi da in uscita appunto il numero relativo al bit che si trova ad uno all'interno di una stringa.

Grazie,

Silver.

Link al commento
Condividi su altri siti


Non capisco lo scopo di questa funzione: tu hai isogno di sapere la posizione di un qualsiasi bit ON in una tabella di bit. E poi che te ne fai di questa posizione? Ho idea che ci possano essere altre soluzioni, è forse per questo che non si è pensata una FC di questo tipo...

Link al commento
Condividi su altri siti

Puoi sempre fare un AND logico con il peso del bit da testare , al limite puoi farti una funzione in cui passi come parametro il bit da testare e ti calcoli con uno Shift di 1 a destra di x bit per ottenere la maschera per fare l'AND.

Ciao B)

Link al commento
Condividi su altri siti

si in effetti detta cosi' sembra molto inutile.....

Comunque vi spiego perche la usavo.

Io programmo seguendo un diagramma sfc e quindi ho tanti bit che mi indicano in che step mi trovo.

Quindi con quella funzione potevo in ogni momento visualizzare per esempio sul pannello operatore in che step mi trovavo nel gruppo 1 ....2 eccc.

Non so se sono stato chiaro.

Calcola che i miei sfc hanno 1 solo step attivo alla volta.

Link al commento
Condividi su altri siti

la serie di operazioni a bit ge sono molto comode BtiPos puoi emularla analizzando la word e settando di conseguanza una seconda word, attenzione pero' che il risultato non e' cosi' intelligente perche' se due bit sono alti non funziona:

se word1 = 1 1->word2

se word1 = 2 2->word2

se word1 = 4 3->word2

se word1 = 8 4->word2

  fino a

se word1 = -1 16->word2

un po' incasinata ma funziona

Modificato: da Piero Azzoni
Link al commento
Condividi su altri siti

grazie piero!

Avevo pensato anche io ad una cosa del genere ma quando devo trovare il bit in un gruppo che ha piu' di 100 step cioe' molto piu' di una word il lavoro diventa un inferno.....ecco perche' avevo chiesto se esisteva una funzione apposita.

Mannaggia sta siemens.....

Grazie comunque.

Silver

Link al commento
Condividi su altri siti

Prova a compilare questa FC

FUNCTION FC 28 : VOID
TITLE =
VERSION : 0.1


VAR_INPUT
  inizio : BOOL;   //Bit iniziale
  bits : INT;  //Quanti bit
END_VAR
VAR_OUTPUT
  posizione : INT; //Posizione a partire dal bit "inizio" = 0
END_VAR
VAR_TEMP
  contatore : INT; //Conta la posizione
  indirizzo : DINT;    //Indirizzo dell'elemento verificato
END_VAR
BEGIN
NETWORK
TITLE =analisi
//Esamina una stringa di bit e fornisce la posizione dell'unico attivo: 0, 1, 2

      L     P##inizio; // Indirizzo iniziale 
      L     #bits; // numero di bit da analizzare
      +D   ; 
      T     #indirizzo; // indirizzo dell'elemento finale
      L     #bits; // numero di bit da esaminare
cicl: T     #contatore; // Registro di conteggio a decremento
      U     M [#indirizzo]; // se è attivo...
      SPB   fine; // esci con il valore del contatore
      L     #indirizzo; 
      L     L#1; 
      -D   ; // decrementa l'indirizzo
      T     #indirizzo; 
      L     #contatore; // decr. il contatore
      LOOP  cicl; 
fine: T     #posizione; 


END_FUNCTION
e poi a chiamatla cosi':
      CALL  FC    28
       inizio   :=M10.0                 // primo elemento da esaminare
       bits     :=37                    // numero di bit
       posizione:=MW8                   // registro risultato

Probabilmente ti rimarrà il problema dello scambio dei byte.

Link al commento
Condividi su altri siti

Silver, in generale pensa sempre che la posizione di un bit in una parola o doppia parola è uguale all'esponente di 2 che rappresenta in binario. Detto questo faccio un'esempio:

mettiamo di avere il bit 3 ON 1000 = 8

se divido per 2 questo numero otterrò 0100 = 4

se divido ulteriormente avrò 0010 = 2

ed ancora 0001 = 1

Sono state eseguite 3 operazioni di divisione per 2 prima di ottenere come risultato 1, vuoldire che il nostro bit è in posizione 3 (partendo da 0)

Quindi in pratica dividi per 2 ed incrementa un contatore, se il risultato è 1 esci dal loop. Il contatore è la posizione del bit.

Se hai più di 32 bit, sommi al tuo contatore l'offset di 32 e così via.

Tieni a mente anche queste cose benchè il codice di rguaresc e tutto molto più malleabile ed elegante

Link al commento
Condividi su altri siti

ragazzi grazie per i suggerimenti,

purtroppo ora non posso provare, comunque appena sono in ufficio vi faccio sapere come e' andata.

Grazie per il momento.

Silver.

Link al commento
Condividi su altri siti

Partendo da quello che ha detto rddiego, si potrebbe risparmiare qualcosa usando l'istruzione SRD 1 (che equivale a dividere per 2 ma usa un solo passo), poi, grazie a una proprietà della istruzione SRD (vado a memoria, non ho qui nè i manuali nè il soft) si utilizza (mi sembra) il salto SPP (al posto del confronto) per uscire dal loop.

(SPP dovrebbe attivarsi quando il bit che c'era dentro la DWORD viene "shiftato" fuori).

Comunque il codice vincente per ora rimane quello di rguaresc.

Unica nota: se ci sono tanti bit da esaminare ed' è settato l'ultimo, vengono elaborate molte istruzioni prima di ottenere il risultato.

In questo caso si potrebbe ottimizzarlo usando 2 loop: il primo esamina un byte alla volta, e se lo trova diverso da 0 entra nel 2° loop che esamina un bit alla volta (del byte in questione)......... così risolvi anche il problema eventuale dello swap dei bytes!

Link al commento
Condividi su altri siti

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