# S7  Indirekte Adressierung



## Rommani (26 Januar 2009)

Hallo zusammen,
  ich habe ein Problem und zwar möchte ich mit Indirekte Adressierung  zahlen von 1 bis 100 in Datenbaustein  DB10   schreiben   

dh:
   #Array[0]= 1  
   #Array[1]= 2  
  ….
  #Array[99]= 100 

  DATA_BLOCK DB 10
  TITLE =
  VERSION : 0.1
    STRUCT              
     Werten : ARRAY  [0 .. 99 ] OF REAL ;     
    END_STRUCT ;                
  BEGIN
  Zum Einsatz kommt eine CPU 315
  Ein paar Tipps sind willkommen. :wink:
  MFG


----------



## vierlagig (26 Januar 2009)

tipp 1: 100 ist kein realwert
tipp 2: warum die werte aus nem array nehmen, einfacher ist doch selber "berechnen"

daraus ergibt sich tipp 3: nimm eine schleife, leg eine zählvariable an, inkrementiere sie in jedem schleifendurchlauf und shreib sie per


```
*
T      DBD [AR1,P#0.0]
```
tipp 4: erhöhe die adresse mit


```
*
+AR1     P#4.0
```
tipp 5: schau in die FAQ hier im forum zum thema pointer


----------



## volker (26 Januar 2009)

oder über einen index den du mit
sld 3 
in einen pointer wandelst

schau mal hier das beispiel am ende
http://www.sps-forum.de/showthread.php?t=8887


----------



## Rommani (26 Januar 2009)

Hallo vierlagig 
vielen Dank für das schnelle Antworte, aber was meinst du mit "einfacher ist doch selber "berechnen" "

kannst du ma bitte genauer erklären bzw. ein Bsp.

nochmal danke


----------



## vierlagig (26 Januar 2009)

Rommani schrieb:


> Hallo vierlagig
> vielen Dank für das schnelle Antworte, aber was meinst du mit "einfacher ist doch selber "berechnen" "
> 
> kannst du ma bitte genauer erklären bzw. ein Bsp.
> ...




```
*
L     #rInc
L     1.00
+R
T     #rInc
```

vorher natürlich noch rInc initialisieren


----------



## vierlagig (26 Januar 2009)

wobei: wenn das array sowieso schon angelegt ist -> SFC20, da brauchste auch nen pointer, nen any


----------



## Kai (27 Januar 2009)

Rommani schrieb:


> ich habe ein Problem und zwar möchte ich mit Indirekte Adressierung zahlen von 1 bis 100 in Datenbaustein DB10 schreiben
> 
> dh:
> #Array[0]= 1
> ...


 
Hier ist einmal ein kurzes Programmbeispiel für das Schreiben der Werte 1.0 bis 10.0 in einen Datenbaustein:


```
FUNCTION FC 100 : VOID
TITLE =Werte in DB schreiben
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : WERTE
VERSION : 1.0
 
VAR_INPUT
  DB_WERTE : BLOCK_DB ; 
  ANZAHL_WERTE : INT ; 
  WERTE_SCHREIBEN : BOOL ; 
END_VAR
VAR_IN_OUT
  WERTE_SCHREIBEN_FLANKE : BOOL ; 
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ; 
  AR1_REGISTER : DWORD ; 
  WERT : REAL ; 
  SCHLEIFE : INT ; 
END_VAR
BEGIN
NETWORK
TITLE =Werte in DB schreiben
 
      U     #WERTE_SCHREIBEN; // Werte schreiben
      FP    #WERTE_SCHREIBEN_FLANKE; // Werte schreiben Flanke
      NOT   ; 
      BEB   ; // Bausteinende
 
NETWORK
TITLE =Register sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
NETWORK
TITLE =Werte in DB schreiben
 
      AUF   #DB_WERTE; // DB-Werte
 
      L     1.000000e+000; 
      T     #WERT; // Wert
 
      L     P#0.0; 
      LAR1  ; 
 
      L     #ANZAHL_WERTE; // Anzahl Werte
M01:  T     #SCHLEIFE; 
 
      L     #WERT; // Wert
      T     DBD [AR1,P#0.0]; 
 
      L     #WERT; // Wert
      L     1.000000e+000; 
      +R    ; 
      T     #WERT; // Wert
 
      L     P#4.0; 
      +AR1  ; 
 
      L     #SCHLEIFE; 
      LOOP  M01; 
 
NETWORK
TITLE =Register wiederherstellen
 
      AUF   DB [#DB_REGISTER]; // DB-Register
 
      LAR1  #AR1_REGISTER; // AR1-Register
 
END_FUNCTION
```
 
Gruß Kai


----------



## Kai (27 Januar 2009)

Und noch zwei Bilder aus der Simulation mit PLCSIM.

Gruß Kai


----------



## Kai (29 Januar 2009)

Nach Rücksprache mit Rommani hier noch einmal ein leicht geändertes Programmbeispiel:


```
FUNCTION FC 100 : VOID
TITLE =Werte in DB schreiben
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : WERTE
VERSION : 1.0
 
VAR_INPUT
  ARRAY_WERTE : ARRAY  [0 .. 9] OF REAL ; 
  ANZAHL_WERTE : INT ; 
  WERTE_SCHREIBEN : BOOL ; 
END_VAR
VAR_IN_OUT
  WERTE_SCHREIBEN_FLANKE : BOOL ; 
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ; 
  AR1_REGISTER : DWORD ; 
  DB_NUMMER : WORD ; 
  WERT : REAL ; 
  SCHLEIFE : INT ; 
END_VAR
BEGIN
NETWORK
TITLE =Werte in DB schreiben
 
      U     #WERTE_SCHREIBEN; // Werte schreiben
      FP    #WERTE_SCHREIBEN_FLANKE; // Werte schreiben Flanke
      NOT   ; 
      BEB   ; // Bausteinende
 
NETWORK
TITLE =Register sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
NETWORK
TITLE =Werte in DB schreiben
 
      L     P##ARRAY_WERTE; // Pointer
      LAR1  ; 
 
      L     W [AR1,P#0.0]; // DB-Nummer
      T     #DB_NUMMER; 
 
      AUF   DB [#DB_NUMMER]; 
 
      L     D [AR1,P#2.0]; // Bereichszeiger
      LAR1  ; 
 
      L     1.000000e+000; 
      T     #WERT; // Wert
 
      L     #ANZAHL_WERTE; // Anzahl Werte
M01:  T     #SCHLEIFE; 
 
      L     #WERT; // Wert speichern
      T     DBD [AR1,P#0.0]; 
 
      L     #WERT; // Wert erhöhen
      L     1.000000e+000; 
      +R    ; 
      T     #WERT; 
 
      L     P#4.0; 
      +AR1  ; 
 
      L     #SCHLEIFE; 
      LOOP  M01; 
 
NETWORK
TITLE =Register wiederherstellen
 
      AUF   DB [#DB_REGISTER]; // DB-Register
 
      LAR1  #AR1_REGISTER; // AR1-Register
 
END_FUNCTION
```
 
Gruß Kai


----------



## Kai (29 Januar 2009)

Und noch zwei Bilder aus der Simulation mit PLCSIM.

Gruß Kai


----------



## Rommani (29 Januar 2009)

Bestens Dank für euch alle. Besonders Kai


----------



## Rommani (29 Januar 2009)

*S7 Indirekte Adressierung*

Vielen Dank an alle Besonders Kai  :s12:


----------



## vierlagig (29 Januar 2009)

los, einmal geht noch. aller guten dinge sind drei!


----------



## Flux (28 April 2014)

*EDIT:* @Kai's FC_Werte (s. o.)


```
L     P##ARRAY_WERTE; // Pointer
      LAR1  ; 

      L     [COLOR=#ff0000]W [AR1,P#0.0][/COLOR]; // DB-Nummer [COLOR=#ff0000]--> Warum steht hier die DB-Nummer ? [COLOR=#ff0000]In welchem Speicherbereich bin ich hier? Wo ist sowas dokumentiert ?[/COLOR][/COLOR]
      T     #DB_NUMMER; 

      AUF   DB [#DB_NUMMER]; 

      L     [COLOR=#ff0000]D [AR1,P#2.0][/COLOR]; // Bereichszeiger [COLOR=#ff0000]--> Warum steht hier der Bereichszeiger ? In welchem Speicherbereich bin ich hier? Wo ist sowas dokumentiert ?[/COLOR]
      LAR1  ;
```


----------



## bike (28 April 2014)

Flux schrieb:


> ```
> L     P##ARRAY_WERTE; // Pointer
> LAR1  ;
> 
> ...




Stichwort "anypointer".
Und wenn du uns schreibst woher du den Pointer hast, kann dir noch besser geholfen werden.
Es scheint so, als ob du dir ein Programmteil von irgendwo her kopiert hast, der mit diesem Pointer einen der schönen? SFC versorgen.
Könnte von mir sein, wobei es bestimmt tausende Programmzeilen gibt die mehr oder weniger so ausschauen.
Es gibt doch hier auch ein how to do von Volker hier? 

Schreib zusammenhängend, wo du was her kopiert hast und was du nicht verstehst.
Also den gesamten Code, damit man sieht was du überhaupt willst.


bike


----------



## PN/DP (28 April 2014)

@bike
Den Code hat er von Kai hier vom Beitrag #9 zitiert/kopiert.
Es handelt sich nicht um einen ANY-Pointer.

@flux
Das Array wird per Pointer an den FC übergeben (das wird bei jedem Datentyp > 4 Byte so gemacht).
Schau Dir in der Step7-Hilfe den Aufbau des Datentyps POINTER an (Index > Pointerformat > Format des Parametertyps POINTER).

Harald


----------



## Flux (28 April 2014)

Ich hatte dasgleiche in einem FB versucht (also L P##oINT_IDB_NO; LAR1; L W [AR1,P#0.0]; T #oINT_IDB_NO), was aber nur den Wert 0 hervorgebracht hat. Der Pointer erklärt es, da INT <= 4 Byte (liegt die Grenze bei 4 Byte, weil das die AKKU-Breite ist ?)

L DBNO; T #oINT_IDB_NO; führte ebenfalls nicht zum Ziel - was macht L DBNO denn dann genau ??

Meine Frage ist, wie kann ich zur Laufzeit die IDB-Nummer meiner FB-Instanz bestimmen ?


----------



## PN/DP (28 April 2014)

Flux schrieb:


> Meine Frage ist, wie kann ich zur Laufzeit die IDB-Nummer meiner FB-Instanz bestimmen ?




```
L DINO
```
Allerdings ist das nur die halbe Wahrheit. Bei multiinstanzfähigen FB steht die Anfangsadresse der Instanz (Offset im Mutter-IDB) in AR2.




Flux schrieb:


> was macht L DBNO denn dann genau ??


Tippe "L DBNO" in den AWL-Editor und drücke *F1*, das gleiche auch mit "L DINO"
oder Hilfe zu AWL > Inhalt > AWL-Operationen Übersicht > ... sortiert nach deutscher Mnemonik (SIMATIC)


			
				AWL-Operationen sortiert nach deutscher Mnemonik (SIMATIC) schrieb:
			
		

> L DBNO   Lade Nummer Global-DB in AKKU 1
> L DINO   Lade Nummer Instanz-DB in AKKU 1






Flux schrieb:


> Der Pointer erklärt es, da INT <= 4 Byte (liegt die Grenze bei 4 Byte, weil das die AKKU-Breite ist ?)


Nicht ganz.
Elementare Datentypen werden als Wert (Kopie, ByVal) übergeben.
Zusammengesetzte Datentypen werden als POINTER (Referenz, ByRef) übergeben.

Harald


----------



## Flux (2 Mai 2014)

Nochmal ne Frage zu o. g. Code:

```
L     P##ARRAY_WERTE; // Pointer: Gehen hierbei nicht Byte 4 und 5 des Pointer verloren, da der AKKU1 nur 4 Byte groß ist ??
      LAR1  ; 


      L     W [AR1,P#0.0]; // DB-Nummer: die ersten zwei Byte im Pointer
      T     #DB_NUMMER; 


      AUF   DB [#DB_NUMMER]; 


      L     D [AR1,P#2.0]; // Bereichszeiger: siehe [B]Frage [/B]
      LAR1  ;

      L     #WERT                       
      T     DBD [AR1,P#0.0]          // DBD bezieht sich auf das zuvor geladene DB-Register
```

*Frage*:
Bezieht sich diese Anweisung 1. auf das zuvor geladene DB-Register oder liest es 2. einen Teil aus dem Pointer?
Wenn 1, müsste es dann nicht DBD [...] heissen ?
Wenn 2., warum heisst es dann nicht L B [AR1, P#2.0], wenn nur der Bereichszeiger gemeint ist ? Laut Pointer-Format-Doku steht im Byte 2 der Speicherbereich.


----------

