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

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 21

Thema: Verständnisproblem mit AR in Schleife

  1. #1
    Registriert seit
    05.10.2006
    Beiträge
    324
    Danke
    11
    Erhielt 8 Danke für 7 Beiträge

    Frage


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo zusammen,

    ich möchte einen Standartbaustein für Statistiken schreiben. Dazu hab ich einen Statistik_DB der folgendermaßen aufgebaut sein kann:

    Code:
    Statistik_Kamera : STRUCT
    Anzahl_Aufnahme_1 : INT
    Anzahl_Aufnahme_2 : INT
    Anzahl_Aufnahme_3 : INT
    Anzahl_Aufnahme_4 : INT
    Anzahl_Aufnahme_5 : INT
    Anzahl_Aufnahme_6 : INT
    Anzahl_Aufnahme_7 : INT
    Anzahl_Aufnahme_8 : INT
    END_STRUCT
    Die Anzahl der Aufnahmen kann variieren.

    Nun habe ich einen Statistik FB welcher die Daten verwalten soll. Ich möchte dem Baustein als IN Parameter die Anzahl der Stationen als INT vorgeben und die oben genannte Struktur als ANY IN_OUT.

    Code:
    IN Parameter:
    IN_INT_Anzahl Stationen : INT
    
    IN OUT Parameter:
    IN_OUT_ANY_Register : ANY
    
    STAT Parameter:
    Statistik_Register_lokal : Array [0..127] Of Int
    nun möchte ich die Daten des DB auf die lokale Variable "Statistik_Register_lokal" umkopieren, die Größe kann je nach übergebener Anzahl unterschiedlich sein, daher dachte ich das ist mit einer Schleife am besten zu lösen. Hier mein Ansatz:

    Code:
      TAR2  
          T     #T_DW_AR2_Sicherung         // Sichern Adressregister
          L     DW#16#FFFFF                 // nicht relevante Bits ausblenden
          UD    
          T     #T_DW_Instanzanfang         // Anfang der Instanzdaten merken
    
          L     P##IN_OUT_ANY_Register
          +D    
          LAR2                              // Zeiger AR2 auf DB setzen
          L     W [AR2,P#4.0]               // und auslesen
          T     #T_INT_DB_Komponente        // DB für Komponente aufschlagen
          AUF   DB [#T_INT_DB_Komponente]
    
          L     D [AR2,P#6.0]               // Zeiger AR2 auf DW setzen
          T     #T_DW_Dat_Komponente
          LAR2  
    
    
          LAR1  P##Statistik_Register       // Zeiger AR1 auf T_Struktur setzen
    
          L     0
          T     #ST_INT_CopySchleife
    
          L     #IN_INT_Anzahl_Stationen
    N1:   T     #ST_INT_CopySchleife
    
          L     W [AR2,P#0.0]               //Kopiere Daten 
          T     W [AR1,P#0.0]
    
          L     P#2.0
          +AR1  
          +AR2  
      
          L     #ST_INT_CopySchleife
          LOOP  N1
    
          LAR2  #T_DW_AR2_Sicherung         // Rücksichern Adressregister AR2
    Nun geht aber meine CPU in Stop wegen "Bereichslängenfehler beim Lesen".
    Kann das allerdings nicht verstehen, die Schleife läuft falls 8 Stationen übergeben werden ja auch nur 8 mal durch.

    Warum wird dann hier in einem nicht vorhanden Speicherbereich gelesen?

    Wenn ich +AR2 auskommentiere gibt es keine Probleme. Dann wird der erste Datensatz des DBs auf die lokale Daten 8 mal kopiert.

    Aber solbald ich +AR2 wieder aktiv schalte geht die CPU in Stop!



    Grüße Pico
    Zitieren Zitieren Verständnisproblem mit AR in Schleife  

  2. #2
    Registriert seit
    20.06.2003
    Ort
    Sauerland.NRW.Deutschland
    Beiträge
    4.850
    Danke
    78
    Erhielt 800 Danke für 543 Beiträge

    Standard

    ist das ein FB?
    da gelten andere regeln für das ar2 in einem fc
    Das DI-Register und das Adressregister AR2 werden systemseitig für den FB- und Multiinstanz-CALL verwendet und dürfen deshalb innerhalb von FB's nicht verändert werden.
    Das Adressregister AR1 wird von einem Teil der ladbaren Standardbausteine verwendet.
    Der Befehl "L P#Parametername" lädt innerhalb eines FB den Adressoffset des angegebenen Parameters, relativ zum Adressregister AR2. Um in multiinstanzfähigen FBs den absoluten Offset im Instanzdatenbaustein zu ermitteln, muss zu diesem Wert noch der bereichsinterne Zeiger (nur Adresse) des AR2-Registers addiert werden.
    Weitere Information zu den Registern der CPU finden Sie in der Hilfe zur Programmiersprache (KOP/FUP/AWL).
    schau dir auch mal sfc20 an
    Geändert von volker (22.03.2013 um 10:30 Uhr)
    .
    mfg Volker .......... .. alles wird gut ..

    =>Meine Homepage .. direkt zum Download

    Meine Definition von TIA: Total Inakzeptable Applikation

  3. #3
    Pico1184 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    05.10.2006
    Beiträge
    324
    Danke
    11
    Erhielt 8 Danke für 7 Beiträge

    Standard

    da gelten andere regeln für das ar2 in einem fc
    Ja das ist ein FB aber das ist mir schon klar. Ich rette ja das AR2 am Anfang des FB, arbeite dann mit dem AR2,
    addiere den ausgerechneten Instanzanfang und sichere das AR2 danch zurück, daher sollte das ja eigentlich funktionieren?!?!?

    Sichern des AR2 und berechnen des Instanzanfangs:
    Code:
    TAR2
    T     #T_DW_AR2_Sicherung         // Sichern Adressregister      
    L     DW#16#FFFFF                 // nicht relevante Bits ausblenden       
    UD           
    T     #T_DW_Instanzanfang         // Anfang der Instanzdaten merken        
    L     P##IN_OUT_ANY_Register       
    +D           
    LAR2
    Rückschreiben des AR2:

    Code:
     LAR2  #T_DW_AR2_Sicherung         // Rücksichern Adressregister AR2
    Grüße Pico
    Geändert von Pico1184 (22.03.2013 um 11:14 Uhr)

  4. #4
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.192
    Danke
    925
    Erhielt 3.292 Danke für 2.661 Beiträge

    Standard

    Bei jedem Zugriff auf Instanz-Variablen des FB (außer auf TEMP-Variablen) muß AR2 seinen originalen Inhalt vom Bausteinaufruf haben.

    Wenn der FB als "multiinstanzfähig" erstellt wurde, dann macht der FB "unsichtbar" bei jedem Instanzvariablenzugriff die erwähnte Offset-Berechnung mit dem Inhalt des AR2 - und geht davon aus, daß AR2 den Inhalt vom Bausteinaufruf hat.

    Also: vor jedem Instanzvariablen-Zugriff AR2 wiederherstellen.

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  5. #5
    Pico1184 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    05.10.2006
    Beiträge
    324
    Danke
    11
    Erhielt 8 Danke für 7 Beiträge

    Standard

    Also: vor jedem Instanzvariablen-Zugriff AR2 wiederherstellen.
    Also ist mein Problem genau hier??? Bzw. die Schleifenvariable.....

    Code:
    N1:   T     #ST_INT_CopySchleife 
            L     W [AR2,P#0.0]               //Kopiere Daten        
            T     W [AR1,P#0.0]        
            L     P#2.0       
            +AR1
            +AR2 
            L     #ST_INT_CopySchleife 
            LOOP  N1
    Grüße Pico

  6. #6
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.192
    Danke
    925
    Erhielt 3.292 Danke für 2.661 Beiträge

    Standard

    Nicht nur der Zugriff auf die STAT-Variablen. Auch der Zugriff auf die IN-, OUT-, IN_OUT-Variablen - auf alle Instanz-Variablen eben.
    (öffne mal den Instanz-DB - alle Variablen die Du da findest).

    Also das Programm möglichst so umformen, daß in der Schleife nur mit TEMP-Variablen gearbeitet wird. Dann muß AR2 nicht so oft wieder hergestellt werden.

    Theoretisch kann man auch einen FB erstellen, der nicht multiinstanzfähig ist - dann kann man AR2 nach belieben nutzen. Würde ich aber nicht machen, das vergisst man irgendwann und kopiert Code und wundert sich, warum der nicht funzt.

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  7. #7
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.192
    Danke
    925
    Erhielt 3.292 Danke für 2.661 Beiträge

    Standard

    Nochwas:
    Du sicherst Dir am Bausteinanfang den Offsetanteil des AR2 in #T_DW_Instanzanfang, benutzt in aber in dem uns gezeigten Code nie.
    Bei "LAR1 P##Statistik_Register" muß dieser Instanzanfang noch addiert werden wenn #Statistik_Register keine TEMP- sondern eine STAT- bzw. Instanz-Variable ist. Wenn Du Deinen FB nicht als Multiinstanz sondern mit einem eigenen IDB aufrufst, dann ist der Instanzanfang aus AR2 allerdings 0 und es fällt nicht auf, daß diese Addition von 0 nicht erfolgt ist.

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  8. #8
    Pico1184 ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    05.10.2006
    Beiträge
    324
    Danke
    11
    Erhielt 8 Danke für 7 Beiträge

    Standard

    so sollte es jetzt mal funktionieren bzw. mein Test hat nun funktioniert:

    Code:
    //Instanzanfang berechnen
          TAR2  
          T     #T_DW_AR2_Sicherung         // Sichern Adressregister
          L     DW#16#FFFFF                 // nicht relevante Bits ausblenden
          UD    
          T     #T_DW_Instanzanfang         // Anfang der Instanzdaten merken
    
          L     P##Statistik_Register       // Zeiger AR1 auf T_Struktur setzen
          +D    
          LAR1  
    
    //Initialisierungen
          L     0
          T     #ST_INT_CopySchleife
          T     #T_INT_Schleifenzaehler
    
    
    //Schleife
          L     #IN_INT_Anzahl_Stationen
    N1:   T     #ST_INT_CopySchleife
    
          L     #T_DW_Instanzanfang
          L     P##IN_OUT_ANY_Register
          +D    
          LAR2                              // Zeiger AR2 auf DB setzen
    
          L     W [AR2,P#4.0]               // und auslesen
          T     #T_INT_DB_Komponente        // DB für Komponente aufschlagen
          AUF   DB [#T_INT_DB_Komponente]
    
          L     D [AR2,P#6.0]               // Zeiger AR2 auf DW setzen
          T     #T_DW_Dat_Komponente
          LAR2  
    
    //Zeiger berechnen und Offset für AR2 einstellen
          L     #T_INT_Schleifenzaehler
          L     16
          *I    
          T     #T_DWORD_Zeiger
          +AR2  
    
    //Daten kopieren
          L     W [AR2,P#0.0]
          T     W [AR1,P#0.0]
    
    //Offset AR1 einstellen
          +AR1  P#2.0
    
    // Rücksichern Adressregister AR2
          LAR2  #T_DW_AR2_Sicherung
    
    //Schleifenzähler inkrementieren
          L     #T_INT_Schleifenzaehler
          L     1
          +I    
          T     #T_INT_Schleifenzaehler
    
    //Schleifenende prüfen
          L     #ST_INT_CopySchleife
          LOOP  N1
    Die einzigste Sorge bereitet mir jetzt noch die Temp Variable "T_INT_Schleifenzaehler".
    Ich inkrementiere diese ja am Ende der Schleife und bilde mir daraus den bereichsinternen Zeiger.

    Im nächsten Zyklus ist ja aber eigentlich der Wert der Temp Variablen wieder verschwunden....aber komischerweise funktioniert es trotzdem?!?!?

    Grüße Pico

  9. #9
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.222
    Danke
    533
    Erhielt 2.698 Danke für 1.950 Beiträge

    Standard

    Zitat Zitat von Pico1184 Beitrag anzeigen
    so sollte es jetzt mal funktionieren bzw. mein Test hat nun funktioniert:

    Code:
    //Instanzanfang berechnen
          TAR2  
          T     #T_DW_AR2_Sicherung         // Sichern Adressregister
          L     DW#16#FFFFF                 // nicht relevante Bits ausblenden
          UD    
          T     #T_DW_Instanzanfang         // Anfang der Instanzdaten merken
    
          L     P##Statistik_Register       // Zeiger AR1 auf T_Struktur setzen
          +D    
          LAR1  
    
    //Initialisierungen
          L     0
          T     #ST_INT_CopySchleife
          T     #T_INT_Schleifenzaehler
    
    
    //Schleife
          L     #IN_INT_Anzahl_Stationen
    N1:   T     #ST_INT_CopySchleife
    
          L     #T_DW_Instanzanfang
          L     P##IN_OUT_ANY_Register
          +D    
          LAR2                              // Zeiger AR2 auf DB setzen
    
          L     W [AR2,P#4.0]               // und auslesen
          T     #T_INT_DB_Komponente        // DB für Komponente aufschlagen
          AUF   DB [#T_INT_DB_Komponente]
    
          L     D [AR2,P#6.0]               // Zeiger AR2 auf DW setzen
          T     #T_DW_Dat_Komponente
          LAR2  
    
    //Zeiger berechnen und Offset für AR2 einstellen
          L     #T_INT_Schleifenzaehler
          L     16
          *I    
          T     #T_DWORD_Zeiger
          +AR2  
    
    //Daten kopieren
          L     W [AR2,P#0.0]
          T     W [AR1,P#0.0]
    
    //Offset AR1 einstellen
          +AR1  P#2.0
    
    // Rücksichern Adressregister AR2
          LAR2  #T_DW_AR2_Sicherung
    
    //Schleifenzähler inkrementieren
          L     #T_INT_Schleifenzaehler
          L     1
          +I    
          T     #T_INT_Schleifenzaehler
    
    //Schleifenende prüfen
          L     #ST_INT_CopySchleife
          LOOP  N1
    Die einzigste Sorge bereitet mir jetzt noch die Temp Variable "T_INT_Schleifenzaehler".
    Ich inkrementiere diese ja am Ende der Schleife und bilde mir daraus den bereichsinternen Zeiger.

    Im nächsten Zyklus ist ja aber eigentlich der Wert der Temp Variablen wieder verschwunden....aber komischerweise funktioniert es trotzdem?!?!?

    Grüße Pico
    Da brauchst du dir keine Sorgen zu machen, du arbeitest die Schleife komplett in einem Zyklus ab (Loop). Vor der Schleife initialisierst du "T_INT_Schleifenzaehler" mit 0, also machst du das richtig.

    Aber du solltest den Hinweis in einer Antwort weiter oben beachten, dein FB ist nicht multiinstanzfähig. Das ist nicht weiter schlimm, wenn du ihn nicht in einer Multiinstanz einzusetzen gedenkst. Wenn doch muß bei der Adressberechnung noch der Offset der Daten im Multiinstanz-DB beachtet werden, den du im AR2 am Anfang praktischerweise ohnehin absicherst.

    PS. Siehe den Beitrag von PN/DP zu diesem Thema.
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  10. #10
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.222
    Danke
    533
    Erhielt 2.698 Danke für 1.950 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Code:
    //Zeiger berechnen und Offset für AR2 einstellen     
    L     #T_INT_Schleifenzaehler      
    L     16      
    *I          
    T     #T_DWORD_Zeiger      
    +AR2

    Zur Sicherheit würde ich aus

    *I noch ein *D machen, man weiß ja nie, ob man irgendwann mal doch sehr viele Daten kopieren will und der berechnete Pointer ist ja eigentlich ein DWORD.
    Auch wenn man später mal Code kopiert, kann das *I Ärger bereiten.
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

Ähnliche Themen

  1. Antworten: 7
    Letzter Beitrag: 15.08.2011, 16:41
  2. Kurze Frage zu ASCII --> Verständnisproblem mit CR
    Von Günter_Pecki im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 26.05.2011, 01:32
  3. Mit Schleife DB füllen
    Von htw im Forum Simatic
    Antworten: 59
    Letzter Beitrag: 23.05.2011, 18:29
  4. Antworten: 22
    Letzter Beitrag: 14.01.2011, 12:10
  5. Verständnisproblem mit pointer ?
    Von Waelder im Forum Simatic
    Antworten: 1
    Letzter Beitrag: 03.08.2009, 09:02

Lesezeichen

Berechtigungen

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