TIA Umsetzung code in SCL TIA V16

guenni

Level-2
Beiträge
316
Reaktionspunkte
34
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Ich bin gerade dabei ein Shift register mit vaiabler Länge welches in AWL existiert in SCL umzusetzen damit ich es in allen SPS Typen einsetzen kann.


Code:
 UN    #shift
      SPB   End

// lenght of Shift Register
      L     8                    // 8 Doppelword =8x32Bit     
      T     #lg


      L     0
      LAR1
LP1:  NOP 0
      AUF   %DB800  // soll variabel werden


      U DBX [ AR1 , P#3.7 ]
      =     #Pos_32
      L DBD [ AR1 , P#0.0 ]
      TAD
      SLD   1
      TAD
      T DBD [ AR1 , P#0.0 ]


// Overflow next Word


      U     #Pos_32
      =     #Pos_0
      +AR1  P#4.0


      L     #lg
      L     1
      -I
      T     #lg


      SPP   LP1
End:  NOP 0

Kann ich alles so umsetzen.

Gruss
Guenni
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielleicht schreibst Du besser eine neue Spezifikation was das Schieberegister können soll und programmierst es komplett neu und vollsymbolisch in SCL?

(Der AWL-Code sieht nicht so aus als ob er funktionieren würde, und variable Register-Länge hat er auch nicht.)

Harald
 
Hallo Harald

Ich will ein Schieberegister programmieren wo ich vorgeben kann wie viele Doppelwörter es lang sein soll. In meinem Auszug war 8 fix. des weiteren will ich es in einer Variablentabelle so beobachten können wenn das letzte bit aktiv wird im Folgewort Bit 0 aktiv ist und nicht Bit 16 deswegen waren die beiden TAD Anweisungen drin.

Nur weis ich nicht wie die Befehle in SCL gehen für die indirekte Programmierung. Da kenn ich mich zu wenig aus bzw. hab noch keine Erfahrung.


Gruss
Guenni
 
Moin guenni,

hier mal, was ich verstehe:

- es sollen Doppelwörter durch ein Schieberegister durchgeschoben werden
- ...

Fragen:

- wir wird das letzte Bit aktiv?
- wie und wo greifst Du auf ein Folgebit zu?
- was hat Bit 16 damit zu tun?
- wie willst Du eine Schleife, die in einem SPS-Zyklus durchläuft in einer Variablentabelle beobachten können?

- was erwartest Du von Deinem Baustein?
- was enthalten die Doppelwörter für Werte?
- woher kommt der nächste Eintrag in das Schieberegister?

Möglichkeiten:

- die Array-Größe kann leicht über eine Konstante bestimmt werden.
- innerhalb des Bausteins kann man die Arraygrenzen auslesen und eine entsprechende FOR-Schleife erstellen.
- einzelne Bits kann man gut über den Slice-Zugriff lesen/schreiben



VG

MFreiberger
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich möchte dbd0. 0 setzen dieses will ich mit einem Ereignis weiterschieben. Je nach Anwendung geht das über mehrere Doppelworte. Zum beobachten wäre es super wenn beim Übergang zum nächsten DW das bit 0.0 kommt. Deswegen war in der AWL Lösung die TAD Anweisungen
drin. In meinen 1 Post war die Länge fix auf 8 DW.

Gesendet von meinem CLT-L29 mit Tapatalk
 
Moin guenni,

warum müssen es unbedingt Doppelworte sein? Ein Array[0..nn] of Bool wäre einfacher.

Wenn ich es richtig verstehe, hakt es an dem Übergang von einem zum nächsten Doppelwort bzw. stellt sich da die Frage, wie man am elegantesten das Bit überträgt?

Es gibt bestimmt viele Variaten. Ein Möglichkeit wäre, das Array[0..n] of DWord in ein Array[0..nn] of Bool zu übertragen, darin in einer FOR-Schleife zu schieben und das Array[0..nn] of Bool wieder zurück auf das Array[0..n] of DWord zu schreiben.

Andere Idee (Pseudocode(ungetestet)):


Code:
VAR_INPUT
    Ix_nextFlag : Bool;
END_VAR


VAR_IN_OUT
    IO_slideRegister : Array
[*] of DWord;
    IOx_auxFlag31 : Bool;
    IOx_auxFlag0 : Bool;
END_VAR


VAR_TEMP
    i : int;
    Ti_lowerBound : int;
    Ti_upperBound : int;
END_VAR


BEGIN

    #Ti_lowerBound := DINT_TO_INT(LOWER_BOUND(ARR := #IO_slideRegister, DIM := 1));
    #Ti_upperBound := DINT_TO_INT(UPPER_BOUND(ARR := #IO_slideRegister, DIM := 1));

    FOR
        #i := #Ti_lowerBound TO #Ti_upperBound
    DO

        #IOx_auxFlag31 := #IO_slideRegister[#i].%x31;
        #IO_slideRegister[#i].%x31 := #IO_slideRegister[#i].%x30;
        #IO_slideRegister[#i].%x30 := #IO_slideRegister[#i].%x29;
        #IO_slideRegister[#i].%x29 := #IO_slideRegister[#i].%x28;
        #IO_slideRegister[#i].%x28 := #IO_slideRegister[#i].%x27;
        #IO_slideRegister[#i].%x27 := #IO_slideRegister[#i].%x26;
        #IO_slideRegister[#i].%x26 := #IO_slideRegister[#i].%x25;
        #IO_slideRegister[#i].%x25 := #IO_slideRegister[#i].%x24;
        #IO_slideRegister[#i].%x24 := #IO_slideRegister[#i].%x23;
        #IO_slideRegister[#i].%x23 := #IO_slideRegister[#i].%x22;
        #IO_slideRegister[#i].%x22 := #IO_slideRegister[#i].%x21;
        #IO_slideRegister[#i].%x21 := #IO_slideRegister[#i].%x20;
        #IO_slideRegister[#i].%x20 := #IO_slideRegister[#i].%x19;
        #IO_slideRegister[#i].%x19 := #IO_slideRegister[#i].%x18;
        #IO_slideRegister[#i].%x18 := #IO_slideRegister[#i].%x17;
        #IO_slideRegister[#i].%x17 := #IO_slideRegister[#i].%x16;
        #IO_slideRegister[#i].%x16 := #IO_slideRegister[#i].%x15;
        #IO_slideRegister[#i].%x15 := #IO_slideRegister[#i].%x14;
        #IO_slideRegister[#i].%x14 := #IO_slideRegister[#i].%x13;
        #IO_slideRegister[#i].%x13 := #IO_slideRegister[#i].%x12;
        #IO_slideRegister[#i].%x12 := #IO_slideRegister[#i].%x11;
        #IO_slideRegister[#i].%x11 := #IO_slideRegister[#i].%x10;
        #IO_slideRegister[#i].%x10 := #IO_slideRegister[#i].%x9;
        #IO_slideRegister[#i].%x9 := #IO_slideRegister[#i].%x8;
        #IO_slideRegister[#i].%x8 := #IO_slideRegister[#i].%x7;
        #IO_slideRegister[#i].%x7 := #IO_slideRegister[#i].%x6;
        #IO_slideRegister[#i].%x6 := #IO_slideRegister[#i].%x5;
        #IO_slideRegister[#i].%x5 := #IO_slideRegister[#i].%x4;
        #IO_slideRegister[#i].%x4 := #IO_slideRegister[#i].%x3;
        #IO_slideRegister[#i].%x3 := #IO_slideRegister[#i].%x2;
        #IO_slideRegister[#i].%x2 := #IO_slideRegister[#i].%x1;
        #IO_slideRegister[#i].%x1 := #IO_slideRegister[#i].%x0;
    
        IF
            #i = 0
        THEN
            #IO_slideRegister[#i].%x0 := #Ix_nextFlag;
        END_IF;

        IF
            #i <= #Ti_upperBound
        THEN
            #IO_slideRegister[#i + 1].%x0 := IOx_auxFlag31;       
        END_IF;

    END_FOR;

END_FUNCTION


VG

MFreiberger
 
Ich bin gerade dabei ein Shift register mit vaiabler Länge welches in AWL existiert in SCL umzusetzen damit ich es in allen SPS Typen einsetzen kann.
Damit Du den Code für das Bit-Schieberegister ohne große Änderungen in allen S7-Typen einsetzen kannst und auch mit "optimiertem" Speicher, solltest Du es als ARRAY OF BOOL in SCL vollsymbolisch ohne Slice-Zugriffe programmieren. Auf Effizienz darfst Du dann nicht achten.

Achtung bei S7-300/400: die Arraygröße/grenzen kann man nicht dynamisch abfragen

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo
Es müssen nicht zwingend Doppelworte sein wenn es mit rra of bool geht ist es mir genauso recht. Es sollte nur für S7-1200 bzw. 1500 passen die 300/400 er lass ich mal aussen vor.

Wie sieht den der Befehl aus für array of bool schieben.
Entschuldigt wenn ich das so direkt frage. Oder ich seh den Wald vor lauter Bäumen nicht.

Gruss
Guenni
 
Wie sieht den der Befehl aus für array of bool schieben.
Ganz allgemein funktioniert ein Schieberegister für beliebige Datentypen (z.B. auch Bits) so:
runterschieben:
Code:
come_out_value := Array[lowerBound];

FOR i := lowerBound TO upperBound - 1 DO
  Array[i] := Array[i + 1];
END_FOR;

Array[upperBound] := new_value;
oder hochschieben:
Code:
come_out_value := Array[upperBound];

FOR i := upperBound - 1 TO lowerBound BY -1 DO
  Array[i + 1] := Array[i];
END_FOR;

Array[lowerBound] := new_value;

Harald
 
Danke das war die Lösung meines Problems. Dachte der Code wird umfangreicher.
So nun ist aber ein SCL Kurs fällig. Auf die Lösung wäre ich nicht gekommen.
 
Zurück
Oben