TIA Anyzeiger zerlegen in SCL mit einer S7-1500 ?

Paule

Level-1
Beiträge
3.058
Reaktionspunkte
869
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

in Step7 konnte ich mit SCL und der AT Funktion eine Datenstructur (Anyzeiger) in folgenden Teile zerlegen:
DB-Nummer, Länge der Datenstructur, und Anfangsadresse des Zeigers.

Bei TIA in Verbindung mit einer S7-1500 bekomme ich das nicht mehr hin. :confused:
Irgendwie kann ich nur im Eingangsbereich den Datentyp Any angeben.

Ich hoffe Ihr könnt mir weiterhelfen

Danke
 
Meinst du im FB und dort im Stat-Bereich?
Ging das nicht nur bei nicht optimierten DB, also auch FB?
Ist dein FB "optimiert"? Einen Versuch wäre es wert.
Entweder nicht optimiert oder bei der Deklaration im FB bei den Variablen irgendeinen Schalter (weiß grad nicht wie der heißt) aktivieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Ralle,

ja, im FB im Statischen Bereich.
Am FB habe ich unter Eigenschaften > Attribute > optimierter Bausteinzugriff "entfernt".
Der DB den ich "zerpflücken" will hat dieses Attribut ebenfalls nicht mehr, aber soweit bin ich ja noch gar nicht.
Am Datentyp des AT - Aufrufs kann ich kein Any angeben, leider.
Somit nehme ich an, es muss anders funktionieren. :confused:
 
Auf der 1500 ist der ANY im optimierten FB im IN oder INOUT - Bereich erlaubt, bei "nicht optimiert" auch im TEMP.

Wenn man beim optimierten FB eine AT auf einen ANY im IN oder INOUT deklarieren will, muss man zuerst diese seltsame "IM IDB setzen"-Einstellung für die Remanenz treffen.
Dann kann eine AT-Sicht eingetippt werden. Nicht ganz intuitiv.... für mich aber der einfachste Weg...
  1. ANY-Parameter (IN1) deklarieren
  2. Remananzeinstellung auf "Im IDB setzen"
  3. In der Zeile darunter einen weiteren Parameter (IN2) deklarieren und als Datentyp einfach "AT" eintippen und Enter.
  4. Dann wird beim Namen "IN2" rechts noch ein "AT "IN1"" angezeigt und der Datentyp wieder auf ANY gesetzt. Dann einfach dass ANY von IN2 gegen die Struktur tauschen...

Bei "nicht optimierten" Fbs geht man gleich vor, nur die Remananzeinstellung kann man sich sparen.

Wobei... Wenn du einen DB "zerplücken" willst, dann musst du den ohnehin auf "nicht optimiert" setzen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich mache hier moch mal einen alten Thread auf.

Mir will es nicht gelingen DB, Startadresse, Länge in einem FC in SCL für einen Any-Zeiger zu ermitteln.
Im Moment rufe ich im SCL-FC noch einen AWL-FC auf um das hinzukriegen.
Ist aber keine schöne Lösung.
Und mit dem AT tue ich mich irgendwie schwer.
CPU ist eine 300er.

AWL-Code
Code:
      L     P##IN_ANY
      LAR1
      L W [ AR1 , P#2.0 ]
      T     #Laenge
      L W [ AR1 , P#4.0 ]
      T     #DB
      L D [ AR1 , P#6.0 ]
      LAR1
      SRD   3
      T     #Adresse
 
Es gibt einige Einschränkungen wenn man ein AT-Sicht auf ein ANY Zeiger einrichten will.
Für ein FC geht es nur mit das AT Sicht als ein VAR_TEMP Variabel (*).
Für ein FB geht es auch mit das AT Sicht als ein VAR oder VAR_IN.
Vielleicht liegt es daran. Ich vermute die FC bekommst die ANY Zeiger über ein VAR_IN ?

*: In die Hilfe zu AT steht es dass man ein AT Sicht auf ein TEMP Variabel machen kann. Aber es ist mir nicht gelungen ein VAR_IN auf ein VAR_TEMP zu kopieren, und dann damit ein AT Sicht machen.

Meine Erfahrung mit S7-300 ist für STEP7 Klassik.
Ob es anders geht bei S7-300 unter TIA weis ich nicht.
 
OK.
Mir ist es auch nicht gelungen den IN-ANY auf ein TEMP-ANY zu kopieren.
Classic und TIA sollten sich hier nicht viel tun.

Aber wie deklariere ich überhaupt eine AT auf den Zeiger?
Auch wenn es sich dann um eine Temp-Var handeln würde.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja genau.
Ich möchte einen als IN-Parameter übergebenen ANY-Zeiger zerlegen.
In einer FC KEIN FB

Ziel ist in diesem Fall ein Umwandlung von String->Char bzw umgekehrt.
Dieser Baustein ist SCL
Bisher hatte ich dem Baustein die Adressen als INT übergeben.
Das ist aber murks da bei änderung des DB falsche Adressen am IN stehen könnten.

Aktueller Stand ist, dass ich im FC einen weiteren FC aufrufe der mir die Adressen liefert (siehe obiger AWL-CODE)

Aber das ist nicht schön. Ich hätte das gerne komplett gekapselt als eine FC ohne weitere FC aufrufen zu müssen.

Den kompletten Code kann ich morgen mal posten (komme da jetzt gerade nicht mehr dran)
 
Also, deine Deklaration könnte in etwa so aussehen:

Code:
VAR_INPUT
  CHARS                             : ANY;
END_VAR

VAR_TEMP
  ANY_CHARS                         : ANY;
  CH AT ANY_CHARS:
    STRUCT
      ID                            : BYTE;
      TYP                           : BYTE;
      ANZAHL_TYP                    : INT;
      DB_NR                         : WORD;
      ZEIGER                        : DWORD;
    END_STRUCT;
END_VAR

Den ANY kann man dann direkt nach TEMP kopieren:
Code:
ANY_CHARS := CHARS;

Der Rest ist dann z.Bsp. mittels Schieben und Maskieren möglich, z.Bsp.:
Code:
IF SHR(IN:=CH.ZEIGER, N:=24) <> 2#10000100 OR         // kein DB
   CH.TYP <> 16#02                                    // Typ nicht Byte
   THEN RETURN;
END_IF;
 
Danke für die Unterstützung.
Habs hinbekommen
Code:
FUNCTION "5931_ANY_zerlegen_SCL" : Void
TITLE = ANY_zerlegen
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : L
FAMILY : 'String'
VERSION : 2.0
   VAR_INPUT
      Anyzeiger : Any;
   END_VAR

   VAR_OUTPUT
      DB_Nr : Int;
      Startadresse : DInt;
      Laenge : Int;
      ID : Byte;
      Typ : Byte;
   END_VAR

   VAR_TEMP
      t_Any : Any;
      AT_Any AT t_Any : Struct
         ID : Byte;
         Typ : Byte;
         Anzahl : Int;
         DB_Nr : Int;
         Adr : DWord;
      END_STRUCT;
   END_VAR


BEGIN
   
    #t_Any := #Anyzeiger;
    #DB_Nr := #AT_Any.DB_Nr;
    #Startadresse := DWORD_TO_INT(SHR(IN := #AT_Any.Adr AND 16#00ffffff, N := 3));
    #Laenge := #AT_Any.Anzahl;
    #ID := #AT_Any.ID;
    #Typ := #AT_Any.Typ;
   
END_FUNCTION
 
Zurück
Oben