TIA Länge eines Anyzeigers auslesen (S7-1500)

Paule

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

wie kann ich die Länge eines Anyzeigers bei einer 1500ter Steuerung auslesen? Variant?
Früher habe ich das über den Zugriff auf das Adressregister gemacht.
Würde zwar immer noch funktionieren, aber laut Siemens ist der Zugriff auf das Adressregister bei den neuen Steuerung nicht mehr empfehlenswert.

Danke
 
Hallo Paule

eine Variable vom Typ ANY ist immer 10 Bytes lang. Auf allen PLC die diesen Typ unterstützen und die S. bisher verscherbelt hat.

Worauf die Variable zeigt, musst du die Variable fragen. Wenn du über die ANY ein a : Array[0..9] of USInt legst, dann ist
a[2]*256+a[3] die Anzahl vom Typen der in a[1] liegt.
Also stehst du jetzt vor dem Folgeproblem eine Tabelle anzulegen, in der steht

a[1] Type Länge
0 Void 0
1 Bool 1/8
2 Byte 1
3 Char 1
4 Word 2
5 Int 2
...

damit du das auch in Int (nicht USInt) ausmultiplizieren kannst.

'n schön' Tach auch
HB
 
Zuviel Werbung?
-> Hier kostenlos registrieren
eine Variable vom Typ ANY ist immer 10 Bytes lang. Auf allen PLC die diesen Typ unterstützen und die S. bisher verscherbelt hat.
Ja, das ist bekannt
Worauf die Variable zeigt, musst du die Variable fragen. Wenn du über die ANY ein a : Array[0..9] of USInt legst, dann ist
a[2]*256+a[3] die Anzahl vom Typen der in a[1] liegt.
Hier kann ich dir nicht ganz folgen. :confused:
Das die Typ Länge je nach Datentyp unterschiedlich ist, ist auch klar.
Aber der Any kann ja auch eine Struct von unterschiedlichen Datentypen beinhalten.
 
Du willst nicht die Länge des Any-Zeigers auslesen, sondern die Länge des Bereichs wissen, wo der Any hinzeigt wenn ich das richtig verstanden habe.

Ich hab das in V14 so gelöst, dass ich mir eine Size_of Funktion erstellt habe. Der Funktion übergebe ich am IN den Any-Zeiger. In der Funktion hole ich mir mit der AT-Sicht die Daten des Any-Zeigers. In den Daten steht auch die Länge des Bereichs wo der Any hin zeigt. Diese kann man dann auslesen und anhand von Typ und Länge den Bereich ermitteln.
 
So ein Size_of habe ich mir mal für Anys gebaut. Vielleicht hilfts dir ja:
Code:
FUNCTION "ANY_Test" : Void
TITLE = 'ANY_Test'
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : VoR
FAMILY : USR
NAME : Tst
VERSION : 1.8
   VAR_INPUT 
      Anypointer : Any;   
   END_VAR


   VAR_OUTPUT 
      DB_Nr : UInt;
      Byte_addr : UInt;
      Bit_addr : UInt;
      P_type : Word;
      Anzahl : UInt;
      Typ : Byte;
   END_VAR


   VAR_TEMP 
      aLS_PAR : Any;
      pLS_PAR AT aLS_PAR : Struct
         SyntaxID : Byte;
         Bereichstyp : Byte;
         Anzahl_Werte : UInt;
         DB_Nr : UInt;
         Startadresse : DWord;
      END_STRUCT;
   END_VAR




BEGIN
// Für FC in Temp kopieren
    #aLS_PAR := #Anypointer;


    #P_type := DWORD_TO_WORD(SHR(IN := #pLS_PAR.Startadresse, N := 24));
    #Byte_addr := DWORD_TO_UINT(SHR(IN := SHL(IN := #pLS_PAR.Startadresse, N := 13), N := 16));
    #Bit_addr := DWORD_TO_UINT(SHR(IN := SHL(IN := #pLS_PAR.Startadresse, N := 29), N := 29));
    #Anzahl := #pLS_PAR.Anzahl_Werte;
    #DB_Nr := #pLS_PAR.DB_Nr;
    #Typ := #pLS_PAR.Bereichstyp;
END_FUNCTION
 
Genau das meinte ich. :D
Danke m_w
Vielen Dank vollmi für die detailierte Lösung.

Zu erwähnen ist noch, #Anzahl ist immer Anzahl Bytes wenn an #Anypointer nicht ein Pointer angehängt wird. der nicht explizit was anders als Bytes angegeben ist (P#DB100.DBX 10.0 WORD 20). Wenn man da z.B. Symbolisch eine Struktur, UDT whatever anhängt, dann ist die Länge immer in Byte angegeben. Sieht man auch an #Typ.

mfG René
 
Zurück
Oben