Vai al contenuto
PLC Forum


Ritorno di un indirizzo di memoria


marki90

Messaggi consigliati

Ciao a tutti!

volevo creare una funzione che dato un DB in ingresso (INDB) mi ritorna l'indirizzo del massimo valore presente nella DB. Nella mia DB sono presenti solo valori DWORD

 

MD80 = Merker utilizzato per muoversi nel DB

MD84 = Merker che utilizzo per salvarmi il massimo valore


      AUF   #INDB


      L     DBD [MD 80]
      L     MD    84
      <D                                //Se TMAX è minore di DB salta
      SPB   jump

      L     DBD [MD 80]
      T     MD    84                    //Trasferisci TMAX in OUT

// non so cosa scrivere


jump: L     MD    80
      L     32
      +D    
      T     MD    80

 

Spero che qualcuno mi possa aiutare. 

Grazie in anticipo

 

Link al commento
Condividi su altri siti


cosi facendo non metti fine al valore del puntatore. Alla fine verifica se il puntatore è maggiore al valore xy rimetti il puntatore = 0

Se vuoi fare tutto il controllo in una scansione condiziona un salto indietro se il puntatore non è ancora al Massimo, altrimenti metti il puntatore al minimo e finisci il blocco.

Link al commento
Condividi su altri siti

Ciao se dovessi farla in STL io farei cosi:

FUNCTION "val_max_db" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      db_in : Block_DB;
   END_VAR

   VAR_OUTPUT 
      valore_max : DWord;
      indirizzo_max : DWord;
   END_VAR

   VAR_TEMP 
      valore_max_tmp : DWord;
      indirizzo_max_tmp : DWord;
      num_loop : DWord;
      indirizzo_tmp : DWord;
   END_VAR


BEGIN
NETWORK
TITLE = 
      OPN #db_in;
      L DBLG;
      L 4;
      /I;
      L 1;
      -I;
      T #num_loop;
      L P#0.0;
      T #indirizzo_tmp;
      T #indirizzo_max_tmp;
      L DBD[ #indirizzo_max_tmp];
      T #valore_max_tmp;
      L #num_loop;

inizio_loop:      T #num_loop;
      L #indirizzo_tmp;
      L P#4.0;
      +D;
      T #indirizzo_tmp;
      L #valore_max_tmp;
      L DBD[ #indirizzo_tmp];
      >D;
      JC fine_loop;
      T #valore_max_tmp;
      L #indirizzo_tmp;
      T #indirizzo_max_tmp;
fine_loop:      L #num_loop;
      LOOP inizio_loop;

      L #indirizzo_max_tmp;
      T #indirizzo_max;
      L #valore_max_tmp;
      T #valore_max;



END_FUNCTION

ho creato poi questa funzione per testare :

FUNCTION "testa_valore2" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      in_db : Block_DB;
      indirizzo : DWord;
   END_VAR

   VAR_OUTPUT 
      out_dword : DWord;
   END_VAR

   VAR_TEMP 
      indirizzo_tmp : DWord;
   END_VAR


BEGIN
NETWORK
TITLE = 
      L #indirizzo;
      T #indirizzo_tmp;
      OPN #in_db;
      L DBD[ #indirizzo_tmp];
      T #out_dword;




END_FUNCTION

 

ho testato tutto e funziona bene.

 

Oppure potresti anche usare una funzione che riceve in ingresso un elemento del DB (nel tuo caso sceglierai il primo) e il numero degli elementi a partire dai quali vuoi trovare il valore maggiore (con l'indirizzo). In questo caso utilizzo un puntatore Pointer nel seguente modo:

 

FUNCTION "max_valore_DB" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      in_ptr : Pointer;   // primo elemento del blocco dati
      num_elementi : Int;   // numero elementi del blocco dati di doubleWord
   END_VAR

   VAR_OUTPUT 
      indirizzo_max : DWord;   // indirizzo della variabile con valore maggiore nel blocco dati
      max_valore : DWord;   // valore massimo tra tutti gli elementi del blocco dati
   END_VAR

   VAR_TEMP 
      num_db : Word;
      indirizzo_max_tmp : DWord;
      max_valore_tmp : DWord;
      num_loop : Int;
   END_VAR


BEGIN
NETWORK
TITLE = 
      L #num_elementi;
      L 1;
      -I;
      T #num_loop;

      L P##in_ptr;
      LAR1;
      L W[ AR1, P#0.0];
      T #num_db;
      L D[ AR1, P#2.0];
      LAR1;
      T #indirizzo_max_tmp;
      OPN DB[ #num_db];
      L D[ AR1, P#0.0];
      T #max_valore_tmp;
      L #num_loop;
inizio_loop:      T #num_loop;
      TAK;
      +AR1 P#4.0;
      OPN DB[ #num_db];
      L D[ AR1, P#0.0];
      >D;
      JC fine_loop;
      T #max_valore_tmp;
      TAR1;
      T #indirizzo_max_tmp;
      L #max_valore_tmp;
fine_loop:      L #num_loop;
      LOOP inizio_loop;

      L #max_valore_tmp;
      T #max_valore;
      L #indirizzo_max_tmp;
      T #indirizzo_max;
END_FUNCTION

 

l'ultima funzione ti permette quindi di cercare il valore maggiore tra l'i-esimo e il j-esimo elemento (ad esempio tra il quinto elemento e il decimo, ossia facendo puntare il pointer al quinto elemento e scegliendo num_elementi=5)

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