Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 9 von 9

Thema: Variabler Array Index in AWL

  1. #1
    Registriert seit
    09.03.2016
    Beiträge
    3
    Danke
    4
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Leute
    Ich habe schon Verschiedenes zum Thema gelesen inkl. der Step7 Hilfe, jedoch werde ich nicht recht schlau.
    Wie bereits zu erkennen möchte ich auf ein Array mit variablem Index zugreifen... und zwar schreibend.

    Konkret:
    Ich habe ein DB20 mit einem Array[1..8] of BYTE. Das Array trägt den Namen "Formnest" und beginnt bei der Adresse 10.0
    Aus dem MB23 hol ich mir die Index-Nr. also je nach Zustand der Anlage 1-8. Wenn nun der Index 3 ist, soll das Array-Element 3 (Formnest[3]) mit 0 überschrieben werden. Wie stelle ich das an, dass dies mit dem variablen Index funktioniert?
    Scheinbar muss das ja mit indirekter Adressierung gelöst werden. Aus den Beiträgen der Step7-Hilfe und im Forum werde ich aber nicht recht schlau. Kann mir jemand helfen?

    Besten Dank und Gruss

    Lyrim
    Zitieren Zitieren Variabler Array Index in AWL  

  2. #2
    Registriert seit
    15.10.2014
    Beiträge
    92
    Danke
    16
    Erhielt 18 Danke für 15 Beiträge

    Standard

    Hallo Lyrim,

    den Index eines Array's als Variable zu übergeben geht leider nicht in Step7 (Im TIA Portal mit S7-1500 geht es).

    Indirekt:
    Code:
    Auf DB20
    L MB23                              
    SLW 3 
    LAR1 
    
    +ar1 P#10.0 
    
    L DBB [AR1,P#0.0] 
    T Ziel

    Stefan
    Geändert von Stefan592 (09.03.2016 um 16:48 Uhr) Grund: Code korrigiert

  3. Folgender Benutzer sagt Danke zu Stefan592 für den nützlichen Beitrag:

    Lyrim (09.03.2016)

  4. #3
    Lyrim ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    09.03.2016
    Beiträge
    3
    Danke
    4
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Danke für die schnelle Antwort!

    Ja direkt geht es eben nicht, darum ja die Frage

    Solch ähnliche Lösungen wie die deine habe ich eben auch öfters gesehen, verstehe sie aber nicht wirklich.
    Weshalb das schieben nach links um 3 Stellen?
    Was wird nun mit LAR1 geladen? Verstehe die Step7-Hilfe leider echt nicht.

    Und was passiert beim zweiten Ladebefehl? Was bedeutet der Pointer P#0.0 ?

    Verstehe glaube das Konzept der indirekten Adressierung nicht

  5. #4
    Registriert seit
    22.11.2006
    Ort
    CH
    Beiträge
    3.649
    Danke
    789
    Erhielt 655 Danke für 498 Beiträge

    Standard

    Zitat Zitat von Lyrim Beitrag anzeigen
    Solch ähnliche Lösungen wie die deine habe ich eben auch öfters gesehen, verstehe sie aber nicht wirklich.
    Weshalb das schieben nach links um 3 Stellen?
    Weil du mit dem Index ja den Byteoffset angeben willst. die drei rechten bit sind für den Bitoffset pro Byte zuständig.

    [QUOTE]
    Was wird nun mit LAR1 geladen? Verstehe die Step7-Hilfe leider echt nicht.
    [QUOTE]

    In dem Beispiel der Inhalt von MB23. Also sozusagen der index.

    Verstehe glaube das Konzept der indirekten Adressierung nicht
    Da hats gute beispiele für AWL
    Pointer Zeiger FIFO LIFO

    Aber ich sags dir. In SCL ist das ganze so viel einfacher das ich oft genau nur dafür schnell n FC in SCL bastel den ich in AWL aufrufen kann.

    mfG René

  6. Folgender Benutzer sagt Danke zu vollmi für den nützlichen Beitrag:

    Lyrim (09.03.2016)

  7. #5
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.335
    Danke
    932
    Erhielt 3.333 Danke für 2.691 Beiträge

    Standard

    Indirekte Adressierung direkt über Array-Index geht nicht. Du mußt die Zugriffsadresse berechnen.
    (Siehe Hilfe zu AWL > Index > indirekte Adressierung)

    Adresse = (Array_Index * 8) * Element_Größe + Anfangsadresse

    Array_Index: 0 ... (muß * 8, weil Bit-Adressen adressiert werden, wir aber die Byte-Adresse brauchen)
    Element_Größe: 1 = Byte / 2 = Word / 4 = DWord

    Code:
    L #index    // 1..8 (aus MB23)
    + -1        // --> 0..7
    SLD 3       // * 8 --> Byteadresse.0
    
    // * 1 für Byte-Array rechnen nicht nötig
    
    L P#10.0    // Anfangsadresse des Array in DB20
    + D
    T #temp_dw_ArrayAdr  // DWord für Adresse
    
    AUF DB20
    L DBB [#temp_dw_ArrayAdr]  // Byte aus DB20.myArray[#index]
    T #myByte
    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  8. Folgende 2 Benutzer sagen Danke zu PN/DP für den nützlichen Beitrag:

    Lyrim (09.03.2016),vollmi (09.03.2016)

  9. #6
    Registriert seit
    23.07.2009
    Ort
    Österreich
    Beiträge
    2.367
    Danke
    457
    Erhielt 696 Danke für 521 Beiträge

    Standard

    Zwei Dinge würde ich aber sicherheitshalber ändern
    Zitat Zitat von Stefan592 Beitrag anzeigen
    Code:
    L MB23                              
    SLD 3  //Falls mal was anderes als MB23 genommen wird und dessen Wert > 4096 ist
    LAR1 
    
    +Ar1 P#10.0 
    
    Auf DB20  //Falls der Index mal nicht aus einem Merkerbereich sondern DB-Bereich kommt
    L DBB [AR1,P#0.0] 
    T Ziel
    Wenn man so etwas macht würde ich aber eher in die Richtung gehen
    Code:
    //--------------------------------------------------------- Konstanten die einmal zugewiesen werden
    L   20
    T   Db20.DbNum           //DB-Nummer
    L   10
    T   Db20.ArrayOffsetinDB   //Startadresse des Array im DB
    L   8
    T   Db20.ArrayMemCnt       //Anzahl Array-Member
    L   1
    T   Db20.ArrayMemLEN       //Länge es ArrayMember in Byte
    
    
    //--------------------------------------------------------- Variabler Zugriff
    L   #ArrayIndex           //Index prüfen
    L   1
    >=I
    U(
    L   #ArrayIndex
    L   Db20.ArrayMemCnt
    <=I
    )
    SPBN Error
    
    
    L   #ArrayIndex
    +   -1                    //Weil Array[1] = Offset 0
    L   Db20.ArrayMemLEN
    *D
    L   Db20.ArrayOffsetinDB
    +D                         //Ab hier hat man die Startadresse von Array[x]
    SLD 3                      //Pointerformat
    LAR1                      //Adressregister
    
    L     Db20.DbNum    
    T     #DbNr_TEMP           //Variable im Temp-Bereich
    AUF   DB[DbNr_TEMP]        //DB zum lesen öffnen
    L     DBB[AR1,P#0.0]       //Von Array[x] lesen
    T     #ZIEL                //Auf Ziel schreiben
    Wenn man sich seine Offsets und die nötigen Beschreibungen seines Arrays 1x (am besten im selben DB) auf ein paar Werte schreibt, dann kann man später mal (vor allem wenn der indirekte Zugriff an mehreren Stellen im Programm steht) sein Array verschieben/erweitern und muss nur die "Konstanten" anpassen. Dann funktionieren diese Zugriffe auch wenn sich die Adresse/Länge oder gar DbNummer in dem das Array liegt ändert.
    Geändert von RONIN (10.03.2016 um 08:01 Uhr)
    If at first you don't succeed, you're not Van Damme!
    ... or maybe using TIA!

  10. Folgende 2 Benutzer sagen Danke zu RONIN für den nützlichen Beitrag:

    Lyrim (09.03.2016),vollmi (09.03.2016)

  11. #7
    Lyrim ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    09.03.2016
    Beiträge
    3
    Danke
    4
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Vielen Dank für all eure Beispiele und Ausschweifungen!

    Hat mir geholfen und jetzt hab ich's (denke ich) verstanden. Und sonst greife ich gerne auf den Link von "vollmi" zurück.

    Einen schönen Abend euch allen!


    EDIT: eine Frage noch, warum funktioniert das nicht wenn ich die komplette DB-Adresse verwende, sondern nur mit dem AUF Befehl?
    Geändert von Lyrim (09.03.2016 um 17:49 Uhr)

  12. #8
    Registriert seit
    23.07.2009
    Ort
    Österreich
    Beiträge
    2.367
    Danke
    457
    Erhielt 696 Danke für 521 Beiträge

    Standard

    Zitat Zitat von Lyrim Beitrag anzeigen
    EDIT: eine Frage noch, warum funktioniert das nicht wenn ich die komplette DB-Adresse verwende, sondern nur mit dem AUF Befehl?
    Weil die CPU das im Endeffekt auch nicht anders macht. Diese hat ein Adressregister und ein DB-Register.
    Wenn du also im Code also "L DB20.DBB10" schreibst lädt die CPU den Wert 20 ins DB-Register und den Offset p#10.0 ins Adressregister. Über die Kombination aus beiden passiert dann der Zugriff.

    Der AUF-Befehl lädt eine Db-Nummer ins DB-Register und sorgt damit dafür das der Adressregister-basierende Ladebefehl "L DBB[AR1,P#0.0], der ja keine Information über die Datenbaustein-Nummer enthält, auch
    auch auf den richtigen Datenbaustein zugreift.
    Geändert von RONIN (10.03.2016 um 08:00 Uhr)
    If at first you don't succeed, you're not Van Damme!
    ... or maybe using TIA!

  13. #9
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.335
    Danke
    932
    Erhielt 3.333 Danke für 2.691 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Zitat Zitat von Lyrim Beitrag anzeigen
    warum funktioniert das nicht wenn ich die komplette DB-Adresse verwende, sondern nur mit dem AUF Befehl?
    Weil Siemens für die S7-300/400 Anweisungen wie "L DB[dbnr].DBB[adresse]" oder "L DB20.DBB[adresse]" nicht vorgesehen hat. Die DB-Nummer kann nur bei direkt angegebener DB-Adresse (oder Symbol) in der Anweisung mit angegeben werden, nicht bei indirekt angegebener DB-Adresse.
    Genaugenommen gibt es noch nichtmal eine Anweisung wie "L DB20.DBB10" - weil die wird nur vom Editor freundlicherweise so zusammengezogen angezeigt. In Wirklichkeit besteht die Anweisung aus einer DB-losen L-Anweisung mit vorgeschalteter AUF-Anweisung:
    Code:
    L DB10.DBB0
    L DB10.DBB1
    L DB20.DBB2
    
    //ist tatsächlich:
    
    AUF DB10
    L DBB0    //lädt DB10.DBB0
    
    AUF DB10
    L DBB1    //lädt DB10.DBB1
    
    AUF DB20
    L DBB2    //lädt DB20.DBB2
    
    //indirekte Varianten:
    
    AUF DB20
    L DBB [#adresse]
    
    AUF DI20
    L DIB [#adresse]
    
    AUF DB20
    L DBB [AR1, P#0.0]
    Ist in den DB-Zugriffs-Anweisungen keine DB-Nummer angegeben, dann beziehen sie sich auf die zuvor im DB1-Register (DBNO) oder im DB2-Register (DINO) hinterlegte DB-Nummer:
    Code:
    AUF DB10  //lädt die Nummer 10 ins DB1/DBNO-Register
    AUF DI20  //lädt die Nummer 20 ins DB2/DINO-Register
    
    L DBB1    //lädt DB10.DBB1 ~ entspricht quasi DB[DBNO].DBB1
    L DIB2    //lädt DB20.DBB2 ~ entspricht quasi DB[DINO].DBB2
    
    L DBNO    //lädt die Nummer aus dem DB1/DBNO-Register
    L DINO    //lädt die Nummer aus dem DB2/DINO-Register
    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

Ähnliche Themen

  1. Antworten: 5
    Letzter Beitrag: 29.10.2015, 16:05
  2. Antworten: 12
    Letzter Beitrag: 11.08.2015, 18:02
  3. Index Array
    Von peraho im Forum Simatic
    Antworten: 10
    Letzter Beitrag: 16.10.2012, 09:16
  4. Array mit index
    Von bluebird277 im Forum Simatic
    Antworten: 7
    Letzter Beitrag: 29.08.2011, 11:23
  5. Index in S7 AWL
    Von plc_tippser im Forum FAQ
    Antworten: 1
    Letzter Beitrag: 13.07.2006, 10:10

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •