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

Ergebnis 1 bis 5 von 5

Thema: Ringpuffer, Schieberegister Schwiriegkeiten

  1. #1
    Registriert seit
    03.04.2013
    Ort
    Germany
    Beiträge
    18
    Danke
    8
    Erhielt 0 Danke für 0 Beiträge

    Frage


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo zusammen,

    ich habe die hier im Forum diskutierten Themen bezüglich indirekter Adressierung gelesen und anhand der Anforderungen meiner Aufgabenstellung mir einen eigenen Funktionbaustein selbst gebastelt.
    Nun funktioniert das gebrauchte Eintragen der Werte in einen DB mit einem Array von DINT
    hier ist der Code dafür
    Code:
          U     #bit_1
          UN    #bErase
    
          AUF   "Register_Puffer"           //schlägt einen DB mit einem ARRAY[1..20] of DINT auf
          L     #iAnzahl_Werte              //lädt aktuellen index, typ INT
          T     #dIndex
    
          L     #dIndex
          L     4                           //bildet ein Integer, das vielfach einem Doppelwort ist
          *D    
          SLD   3                           //bildet einen Pointer
          LAR1                              //speichert ins Adressregister 1
    
          L     #dTemp_data_in              //lädt den Wert vom typ DINT
          T     DBD [AR1,P#0.0]             //greift auf den DB ARRAY zu, schreibt den Wert unter Adresse des Pointers
    Leider habe ich jetzt Probleme mit dem Schieben der Werte in DB Register, wenn ich den allerersten Wert löschen möchte. Mit diesem Code geht der CPU einfach ins STOP und verweist im Diagnosepuffer auf die letzte Zeile im oberen Code, nämlich wo der erste Schreibzugriff auf DB gescheht

    Code:
         U     #bErase
    //iAnzahl_Werte beinhaltet die nummer des letzten eintrages,
    // dies kann auf seine adresse verweisen
          AUF   "Register_Puffer"
          L     #iAnzahl_Werte
    
    //wir brauchen aber an der Stelle den zweitgeschriebenen Wert in der Tabelle
          L     1
          -I    
          T     #iDekrement
    
    anf:  NOP   0
          L     #iAnzahl_Werte
          L     #iDekrement
          -I    
          T     #dIndex                     //schreibt die nummer des allerersten Eintrages
    
          L     #dIndex
          L     4
          *D    
          SLD   3                           //bildet einen Pointer
          LAR1                              //speichert ins Adressregister 1
    
          L     DBD [AR1,P#4.0]             //greift auf den nächsten nach allerersten Element zu
          T     DBD [AR1,P#0.0]             //überschreibt den Allerersten mit nachfolgendem Element
    
    //hier ist eine Verschiebung des verweisenden Pointers gebraucht
          L     #iDekrement
          L     1
          -I    
          T     #iDekrement
          L     0
          >=I   
          SPB   anf
          SPA   ende
    
    //dekremintiert den Zähler für die anwesenden Einträge in der Tabelle um EINS
    ende: NOP   0
          L     #iAnzahl_Werte
          L     1
          -I    
          T     #iAnzahl_Werte
    Könntet ihr mir, bitte erklären was ich so falsch mache? Oder was eurer Meinung nach bei mir falsch sein könnte?
    Ich gehe selbstständig nicht mehr weiter
    Zitieren Zitieren Ringpuffer, Schieberegister Schwiriegkeiten  

  2. #2
    Registriert seit
    08.04.2008
    Ort
    Köln
    Beiträge
    844
    Danke
    39
    Erhielt 244 Danke für 199 Beiträge

    Standard

    Hallo ChopinJunkie,

    prüf' doch mal Dein #iAnzahl_Werte. Ich vermute es ist kleiner Null.
    Wenn Du eine Prüfung auf kleiner Null am Ende Deines 2. Codeschnipsels anfügst
    und bei <0 das #iAnzahl_Werte auf 0 setzt, soll es funktionieren.

    Grüße
    Gebs

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

    ChopinJunkie (26.04.2014)

  4. #3
    ChopinJunkie ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    03.04.2013
    Ort
    Germany
    Beiträge
    18
    Danke
    8
    Erhielt 0 Danke für 0 Beiträge

    Lächeln

    Zitat Zitat von Gebs Beitrag anzeigen
    Hallo ChopinJunkie,

    prüf' doch mal Dein #iAnzahl_Werte. Ich vermute es ist kleiner Null.
    Wenn Du eine Prüfung auf kleiner Null am Ende Deines 2. Codeschnipsels anfügst
    und bei <0 das #iAnzahl_Werte auf 0 setzt, soll es funktionieren.

    Grüße
    Gebs
    Hallo Gebs,

    danke für deinen Hinweis auf
    Code:
          L     #iAnzahl_Werte
          L     0
          <I    
          L     0
          T     #iAnzahl_Werte
    CPU geht jetzt nicht mehr direkt ins STOP. ABER... iAnzahl_Werte wird offensichtlich ständig mit Null beschrieben, was im Endeffekt einen Fehlschlag beim Befüllen von Array mit Werten verursacht, da keiner Pointer gebildet wird. Die Ursache dafür, meiner Meinung nach liegt am absoluten Sprung auf "ende"
    Geändert von ChopinJunkie (26.04.2014 um 13:05 Uhr)

  5. #4
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.302
    Danke
    932
    Erhielt 3.321 Danke für 2.683 Beiträge

    Standard

    In Step7 gibt es nur wenige Anweisungen, die VKE-abhängig ausgeführt werden (S, R, BEB, CC, SPB, SPBN, ...). Die meisten Anweisungen werden unabhängig vom VKE immer ausgeführt.
    Wenn Programmcode nichts bewirken soll dann darf man ihn nicht ausführen --> dann muß man ihn überspringen:
    Code:
          U     #bit_1
          UN    #bErase
          SPBN  end1
    
          L     #iAnzahl_Werte              //lädt aktuellen index, typ INT
          T     #dIndex
    
          L     #dIndex
          L     4                           //bildet ein Integer, das vielfach einem Doppelwort ist
          *D    
          SLD   3                           //bildet einen Pointer
          LAR1                              //speichert ins Adressregister 1
    
          L     #dTemp_data_in              //lädt den Wert vom typ DINT
          AUF   "Register_Puffer"           //schlägt einen DB mit einem ARRAY[1..20] of DINT auf
          T     DBD [AR1,P#0.0]             //greift auf den DB ARRAY zu, schreibt den Wert unter Adresse des Pointers
    
    end1: SET
    Die AUF-Anweisung gehört so nahe wie möglich zu der Anweisung, wo auf den geöffneten DB zugegriffen wird, um sicherzustellen, daß nicht zwischendurch versehentlich ein anderer DB geöffnet wird.

    Code:
          U     #bErase
          SPBN  end2
    //iAnzahl_Werte beinhaltet die nummer des letzten eintrages,
    // dies kann auf seine adresse verweisen
          L     #iAnzahl_Werte
    
    //wir brauchen aber an der Stelle den zweitgeschriebenen Wert in der Tabelle
    //Vorsicht! wenn #iAnzahl_Werte = 0 dann gibt es wohl keinen "zweitgeschriebenen Wert", #iDekrement wird -1, ist das richtig so???
          L     1
          -I    
          T     #iDekrement
    
          AUF   "Register_Puffer"           //nahe am Zugriff, aber noch vor der Schleife
    anf:  NOP   0
          L     #iAnzahl_Werte
          L     #iDekrement
          -I    
          T     #dIndex                     //schreibt die nummer des allerersten Eintrages
    
          L     #dIndex
          L     4
          *D    
          SLD   3                           //bildet einen Pointer
          LAR1                              //speichert ins Adressregister 1
    
          L     DBD [AR1,P#4.0]             //greift auf den nächsten nach allerersten Element zu
          T     DBD [AR1,P#0.0]             //überschreibt den Allerersten mit nachfolgendem Element
    
    //hier ist eine Verschiebung des verweisenden Pointers gebraucht
          L     #iDekrement
          L     1
          -I    
          T     #iDekrement
          SPPZ  anf                         //hat den gleichen Effekt wie die nachfolgenden 4 Zeilen: springe zu anf wenn Ergebnis >= 0
    //      L     0
    //      >=I   
    //      SPB   anf
    //      SPA   ende                        // <-- SPA ist überflüssig
    
    //dekremintiert den Zähler für die anwesenden Einträge in der Tabelle um EINS
    ende: NOP   0                           // <-- Marke und NOP ist überflüssig
          L     #iAnzahl_Werte
          L     1
          -I    
          SPPZ  TIAW                        //springe wenn Ergebnis >= 0
          L     0                           //bei Ergebnis < 0 durch 0 ersetzen
    TIAW: T     #iAnzahl_Werte
    
    end2: SET
    Statt
    Tip: Als Füll/Dummy-Anweisung an einer Sprungmarke ist eine SET-Anweisung ein kleines bischen besser geeignet als eine NOP-Anweisung (ist kürzer und garantiert eine VKE-Begrenzung).
    An die Sprungmarke kann aber auch gleich eine sinnvolle Anweisung geschrieben werden, wie z.B. "anf: L #iAnzahl_Werte"

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

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  6. Folgender Benutzer sagt Danke zu PN/DP für den nützlichen Beitrag:

    ChopinJunkie (28.04.2014)

  7. #5
    ChopinJunkie ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    03.04.2013
    Ort
    Germany
    Beiträge
    18
    Danke
    8
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    vielen Dank an Harald!

    die Ratschläge waren super hilfreich!!!

Ähnliche Themen

  1. Step 7 Ringpuffer mit SCL
    Von SKNGO im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 28.01.2014, 09:38
  2. Problem mit Ringpuffer
    Von nutellahase im Forum Simatic
    Antworten: 1
    Letzter Beitrag: 12.09.2011, 19:09
  3. Ringpuffer mit Mittelwert
    Von taucherd im Forum Simatic
    Antworten: 28
    Letzter Beitrag: 19.05.2011, 23:30
  4. UDT // Ringpuffer
    Von zloyduh im Forum Simatic
    Antworten: 16
    Letzter Beitrag: 06.03.2011, 08:18
  5. Array bei Datenwechsel speichern in Ringpuffer
    Von Wiedenn? im Forum Simatic
    Antworten: 13
    Letzter Beitrag: 21.03.2010, 04:55

Lesezeichen

Berechtigungen

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