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

Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 36

Thema: Zustandsbits in Zustands-Integer

  1. #1
    Registriert seit
    11.12.2008
    Beiträge
    73
    Danke
    39
    Erhielt 9 Danke für 8 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    ne eigentlich ganz simple aufgabe, die mich gerade überfordert:

    der Zustand eines Maschinenablaufs/einer Arbeitsstation einer Maschine o.ä. kann wahlweise als Integer oder in einer Folge von Bits gespeichert werden.
    dabei ist jedem Bit fest eine Zustandsnummer zugeordnet.

    also als integer

    Code:
    Zst      INT     5
    oder als Bits

    Code:
    Zst1     Bool     FALSE
    Zst2     Bool     FALSE
    Zst3     Bool     FALSE
    Zst4     Bool     FALSE
    Zst5     Bool     TRUE
    ich will nun ein programm schreiben, was variante 2 in variante 1 überführt.
    es soll auch möglich sein, dass eine gewisse anzahl bits/zustände gleichzeitig aktiv sind
    wenn also 5 zustandsbits gleichzeitig aktiv sind, will ich deren zugeordneten zustand in 5 Ints abspeichern


    mir fällt zu dieser simplen Aufgabe gerade nix besseres ein, als

    Code:
    //IN nach TEMP
          L     #QuellDB                    //IN-Var... DB-Nummer Quelle
          T     #QDB                        //TEMP-Var... DB-Nummer Quelle
          L     #ZielDB                     //IN-Var... DB-Nummer Ziel
          T     #ZDB                        //TEMP-Var... DB-Nummer Ziel
    
    // --- initialisieren ---
    //Pointer erstellen
          L     #QuellAnfang                //Byteposition erstes Bit
          SLD   3
          L     #HoechsterZustand           //Anzahl Bits
          +D                                //Pointer auf die Zustandsbits zeigt an
          T     #Bitpointer                 //dieser Stelle noch auf das letzte Bit
    //Zaehler/Merker initialisieren
          L     0
          T     #GefundeneZst
     
    // --- Pruefschleife ---
    //geht Bit fuer Bit durch. sollte eins der Bits true sein, steht im Schleifenzaehler die Nummer des Zustands
          L     #HoechsterZustand           //Anzahl Bits
    nw1b: T     #Schleifenzaehler
          AUF   DB [#QDB]
          LAR1  #Bitpointer
          SET   
          U      [AR1,P#0.0]
          SPBN  nw1c
    //wenn das Bit, auf das Bitpointer gerade zeigt, gesetzt ist
    //Zielposition im Ziel-DB laden
          AUF   DB [#ZDB]
          L     #GefundeneZst               //Anzahl gefundener Zustaende
          SLD                               //*2 um 2 Bytes bzw 1 Int weiterzuspringen
          L     #ZielAnfang                 //IN-Var... Byteposition des ersten Zst-Ints im Ziel-DB
          +D                                //im akku 1 steht die Byte-Nummer des Ints, in das der Zustand gespeichert wird
          SLD   3
          LAR1  
    //gefundenen Zustand abspeichern
          L     #Schleifenzaehler
          T     W [AR1,P#0.0]
    //Zaehler erhoehen
          L     #GefundeneZst
          +     1
          T     #GefundeneZst
    //Abbruchbedingung: speicherplatz fuer Zustandsnummern ist voll
          L     #GefundeneZst
          L     #AnzahlInteger              //IN-Var... Vorgabe der maximal gleichzeitig gesetzten Zst bzw die Anzahl Speicherplaetze
          ==I   
          BEB   
    nw1c: L     #Bitpointer                 //Pointer auf die Zustandsbits um 1 verringern
          +     -1
          T     #Bitpointer
          L     #Schleifenzaehler
          LOOP  nw1b
    umständlich und verbrät vermutlich zuviel Rechenzeit durch die Loopschleife mit unzähligen Durchläufen

    hat vielleicht jemand ne elegantere idee?
    Zitieren Zitieren Zustandsbits in Zustands-Integer  

  2. #2
    Registriert seit
    11.12.2008
    Beiträge
    73
    Danke
    39
    Erhielt 9 Danke für 8 Beiträge

    Standard

    zur Verbesserung der Laufzeit auf Kosten von Speicherplatz und Lesbarkeit dasselbe nochmal mit 2 verschachtelten Schleifen.

    die äußere Schleife prüft den Quellbereich WORD-weise auf gesetzte Bits und wenn mindestens eins gesetzt ist, Schaut die innere Schleife, welche Bits genau gesetzt sind...

    Code:
    //IN nach TEMP
          L     #QuellDB                    //IN-Var... DB-Nummer Quelle
          T     #QDB                        //TEMP-Var... DB-Nummer Quelle
          L     #ZielDB                     //IN-Var... DB-Nummer Ziel
          T     #ZDB                        //TEMP-Var... DB-Nummer Ziel
     
    // --- initialisieren ---
    //Zaehler/Merker initialisieren
          L     0
          T     #GefundeneZst
     
    //Offset der aeusseren Schleife 0 setzen
          L     0
          T     #OffsetAussen
     
    //Zst-Ints im Ziel-DB 0 setzen
          AUF   DB [#ZDB]
          L     #ZielAnfang                 //IN-Var... Byteposition des ersten Zst-Ints im Ziel-DB
          SLD   3
          LAR1  
          L     #AnzahlInteger
    nw1a: T     #SchleifeInnen
          L     0
          T     W [AR1,P#0.0]
          +AR1  P#2.0
          L     #SchleifeInnen
          LOOP  nw1a
     
     
    // --- Pruefschleifen ---
    //*** Pruefschleife aussen: testet je 16 bits, ob überhaupt eins davon gesetzt ist ***
     
          L     #HoechsterZustand           //Anzahl Bits
          SRW   4
          +     1                           //Anzahl Woerter
    nw1b: T     #SchleifeAussen
          AUF   DB [#QDB]
          L     #OffsetAussen               //Anzahl gepruefter Bytes
          L     #QuellAnfang
          +I    
          SLD   3
          T     #QPointer                   //Pointer auf aktuell zu testenden Quellbereich
          LAR1  
     
          L     W [AR1,P#0.0]
          L     0
          ==I   
          SPB   nw1e                        //wenn kein bit true ist, muss man auch nicht schauen, welches true ist
    //***Innere Schleife***
          L     16
    nw1c: T     #SchleifeInnen
          AUF   DB [#QDB]
          L     #QPointer
          L     #SchleifeInnen
          +D    
          +     -1                          //weil Bits von 0..15, aber SchleifeInnen von 1..16
          LAR1  
          SET   
          U      [AR1,P#0.0]
          SPBN  nw1d
    //wenn das Bit, auf das Bitpointer gerade zeigt, gesetzt ist
    //Zielposition im Ziel-DB laden
          AUF   DB [#ZDB]
          L     #GefundeneZst               //Anzahl gefundener Zustaende
          SLD                               //*2 um 2 Bytes bzw 1 Int weiterzuspringen
          L     #ZielAnfang                 //IN-Var... Byteposition des ersten Zst-Ints im Ziel-DB
          +D                                //im akku 1 steht die Byte-Nummer des Ints, in das der Zustand gespeichert wird
          SLD   3
          LAR1  
    //gefundenen Zustand abspeichern
          L     #OffsetAussen               //Anzahl durchsuchter Bytes
          SLW   3                           //Anzahl durchsuchter Bits
          L     #SchleifeInnen              //Position innerhalb des aktuell durchsuchten Wortes
          +I                                //Nummer des dem Bit zugewiesenen Zustands
          T     W [AR1,P#0.0]
    //Zaehler erhoehen
          L     #GefundeneZst
          +     1
          T     #GefundeneZst
    //Abbruchbedingung: speicherplatz fuer Zustandsnummern ist voll
          L     #GefundeneZst
          L     #AnzahlInteger              //IN-Var... Vorgabe der maximal gleichzeitig gesetzten Zst bzw die Anzahl Speicherplaetze
          ==I   
          BEB   
    //Ende innere Schleife
    nw1d: L     #SchleifeInnen
          LOOP  nw1c
    //Ende aeussere Schleife
    nw1e: L     #OffsetAussen
         + 2  
          T     #OffsetAussen               //Anzahl durchsuchter Bytes um 2 erhoehen
          L     #SchleifeAussen
          LOOP  nw1b
    elegant ist aber wirklich was anderes... ich wäre für Anregungen dankbar
    Geändert von Mangokind (05.03.2009 um 14:27 Uhr)

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

    Standard

    Das einzige, was mir auf Anhieb einfällt, wäre, nicht jedesmal die komplette Adresse neu zu berechnen. Statt dieser Neuberechnung in der inneren Schleife könntest du einfach auf den Pointer, der auf das Bit zeigt P#0.1 aufaddieren.
    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

  4. Folgender Benutzer sagt Danke zu Ralle für den nützlichen Beitrag:

    Mangokind (05.03.2009)

  5. #4
    Registriert seit
    11.12.2008
    Beiträge
    73
    Danke
    39
    Erhielt 9 Danke für 8 Beiträge

    Standard

    aber der Wert im AR1 könnte sich ändern, falls ein gesetztes Zustandsbit gefunden wurde

    dann würde ja ein Ziel-DB geöffnet und irgendwo in den hineingeschrieben, wobei AR1 überschrieben würde...

    ich könnte natürlich auch für das eine AR1 nehmen und für das andere AR2...

    gute idee... danke dir!

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

    Standard

    Zitat Zitat von Mangokind Beitrag anzeigen
    aber der Wert im AR1 könnte sich ändern, falls ein gesetztes Zustandsbit gefunden wurde

    dann würde ja ein Ziel-DB geöffnet und irgendwo in den hineingeschrieben, wobei AR1 überschrieben würde...

    ich könnte natürlich auch für das eine AR1 nehmen und für das andere AR2...

    gute idee... danke dir!
    Du berechnest einmal den Pointer beim Eintritt in die Schleife. Der steht ja in einer Variable. Zu dieser einfach P#0.1 dazuaddieren, ins AR1 laden, fertig. Den Pointer würde ich schon nutzen, AR2 mag ich eher nicht so, wegen der FB- und Multiinstanzen.
    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

  7. Folgender Benutzer sagt Danke zu Ralle für den nützlichen Beitrag:

    Mangokind (05.03.2009)

  8. #6
    Registriert seit
    11.12.2008
    Beiträge
    73
    Danke
    39
    Erhielt 9 Danke für 8 Beiträge

    Standard

    das wird ja doch schwieriger als angenommen, da die loopschleife runterzaehlt, also vom letzten zum ersten bit vorgeht, ich aber das adressregister nicht um 1 verringern kann

    bzw ich müsste AR1 nach akku 1 laden, um 1 verringern und akku 1 zurueck nach AR1

    da wäre aber dann jede ersparnis hinüber


    oder ich versteh dich total falsch
    Geändert von Mangokind (05.03.2009 um 10:30 Uhr)

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

    Standard

    Zitat Zitat von Mangokind Beitrag anzeigen
    das wird ja doch schwieriger als angenommen, da die loopschleife runterzaehlt, also vom letzten zum ersten bit vorgeht, ich aber das adressregister nicht um 1 verringern kann
    Probiers einfach mal, wir hatten das schon mal diskutiert. Wenn ich mich recht erinnere, geht es sagar, man kann P#0.1 auch abziehen.
    Andererseits kann die Loopschleife ja ruhig runterzählen und der Pointer erhöht werden, kommt ja nur auf die richtige Startadresse an.

    PS: Ich glaube, du hast Recht, wirklich viel bringt das nicht. So wie du das geschrieben hast findet man sich wenigstens zurecht, das ist ohnehin wichtiger, als vielleicht eine Operation einzusparen.
    Geändert von Ralle (05.03.2009 um 10:33 Uhr)
    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. Folgender Benutzer sagt Danke zu Ralle für den nützlichen Beitrag:

    Mangokind (05.03.2009)

  11. #8
    Registriert seit
    11.09.2007
    Ort
    Suedwestpfalz
    Beiträge
    917
    Danke
    81
    Erhielt 209 Danke für 192 Beiträge

    Standard

    Kleiner Tipp anderer Natur:

    Wenn Du die IN-Variablen der DBs als "Block-DB" ausführst brauchst Du die TEMP_VAR nicht mehr, sondern

    1. kannst die Block_Dbs direkt mit AUF aufrufen

    und
    2. findest Du die DBs wieder in den Querverweisen...

    dtsclipper
    Das Grauen lauert in der Zwischenablage !!

  12. Folgender Benutzer sagt Danke zu dtsclipper für den nützlichen Beitrag:

    Mangokind (05.03.2009)

  13. #9
    Registriert seit
    11.12.2008
    Beiträge
    73
    Danke
    39
    Erhielt 9 Danke für 8 Beiträge

    Standard

    ich glaube, dass mein ansatz insgesamt viel zu umständlich ist.

    rein mathematisch müsste ich mir nur den exponenten zur basis 2 ausgeben lassen, aber ein kurzer blick ins S7 PDF mit der ausführungszeit für logarithmen hat mich ganz schnell wieder von dieser idee abgebracht

    würde den code zwar zu nem 10-zeiler vereinfachen, aber die laufzeit...

    Zitat Zitat von dtsclipper Beitrag anzeigen
    Kleiner Tipp anderer Natur:

    Wenn Du die IN-Variablen der DBs als "Block-DB" ausführst brauchst Du die TEMP_VAR nicht mehr, sondern

    1. kannst die Block_Dbs direkt mit AUF aufrufen

    und
    2. findest Du die DBs wieder in den Querverweisen...

    dtsclipper
    danke dir! aber ich kann keine Parametertypen in DBs speichern... zumindest nicht bei AWL und der Aufruf akzeptiert dann keine Zahlenwerte mehr
    d.h. das Problem mit den TEMP-Vars würde sich in die aufrufende Funktion verlagern
    Geändert von Mangokind (05.03.2009 um 10:43 Uhr)

  14. #10
    Registriert seit
    11.09.2007
    Ort
    Suedwestpfalz
    Beiträge
    917
    Danke
    81
    Erhielt 209 Danke für 192 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ich bin einfach davon ausgegangen das die Dbs schon Existieren...
    Sollen die erst mit dem SFC82 erzeugt werden da die Nummer nicht fix ist ?

    dtsclipper
    Das Grauen lauert in der Zwischenablage !!

Ähnliche Themen

  1. String in Integer
    Von Thorilla im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 24.01.2011, 13:02
  2. integer 32Bit in integer 16 Bit wandeln
    Von slk230-power im Forum Simatic
    Antworten: 11
    Letzter Beitrag: 09.11.2009, 22:35
  3. Integer in Hex
    Von snowkopp im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 22.09.2009, 20:42
  4. Integer, Hex
    Von Anonymous im Forum Simatic
    Antworten: 1
    Letzter Beitrag: 13.01.2006, 22:08
  5. Umwandlung Integer(32bit) in Integer(16bit)
    Von Kojote im Forum Simatic
    Antworten: 4
    Letzter Beitrag: 18.08.2005, 10:56

Lesezeichen

Berechtigungen

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