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




Ritorno di un indirizzo di memoria


Messaggi consigliati

Inserito:

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

 


Inserita:

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.

Inserita:

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)

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