TIA Wie DB-Nummer aus Symbol ermitteln?

Machtnix

Level-2
Beiträge
77
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit dem Step7 Manager und der S7-300/400 und AWL war das kein Problem.

Code:
FUNCTION "FCNumDB" : VOID
TITLE =DB-Nummer aus Symbol ermitteln
VERSION : 1.0

VAR_INPUT
  Sym: BLOCK_DB;
 END_VAR

VAR_IN_OUT
  Num: INT;
 END_VAR

BEGIN
NETWORK
TITLE =

L P#Sym;SRD 16; T #Num;

END_FUNCTION

Im TIA-Portal (V13) für die S7-1500 ist der BLOCK_DB als Datentyp nicht mehr zulässig. Als Ersatz wird DB_ANY empfohlen und die Konvertierungsfunktionen DB_ANY_TO_VARIANT oder DB_ANY_TO_UINT. Als SCL-Code sieht die Funktion nun so aus:

Code:
FUNCTION "FCNumDB" : Void
TITLE = DB-Nummer aus Symbol ermitteln
VERSION : 0.1

   VAR_INPUT 
      Sym : DB_ANY;
   END_VAR

   VAR_IN_OUT 
      Num : INT;
   END_VAR
   
BEGIN

      Num := DB_ANY_TO_UINT(#Sym);
         
END_FUNCTION

Sie lässt sich fehlerfrei übersetzen und laden. Nur leider liefert sie im Einsatz nichts anderes als 0 zurück.

In der Hilfe steht zu DB_ANY_TO_UINT so gut wie nichts. Dafür steht bei DB_ANY_TO_VARIANT etwas, was vermutlich auch auf DB_ANY_TO_UINT zutrifft :

...einen Datenbaustein, der ein Instanz-Datenbaustein eines Funktionsbausteins oder ein globaler Datenbaustein ist. Die Konvertierung der Ausgangsvariablen in den Datentyp VARIANT ist nicht möglich.

Im Klartext: Für die meisten Datenbausteine ist DB_ANY nicht zu gebrauchen. Weiß da jemand eine Lösung?

Es wird zurecht immer wieder empfohlen, rein symbolisch zu programmieren. Dummerweise wird aber immer wieder die Nummer gebraucht. Und mit dem Wegfall der Symboltabelle sind die Nummern nicht mal fest zugeordnet. Seit ich mit TIA arbeiten muss, beginne ich den alten Manager zu lieben.
 
Ich hab's. Mit dem guten alten ANY-Pointer und AWL funzt es:

Code:
FUNCTION "FCNumDB" : VOID
TITLE =DB-Nummer aus Symbol ermitteln
{ S7_Optimized_Access := 'FALSE' }
VERSION : 1.0

VAR_INPUT
  Sym: ANY;
 END_VAR

VAR_IN_OUT
  Num: INT;
 END_VAR

BEGIN
NETWORK
TITLE =

L P##Sym;LAR1;
L W [AR1,P#4.0]; T #Num;

END_FUNCTION
 
Zuviel Werbung?
-> Hier kostenlos registrieren
In SCL sähe das in etwa so aus. Mit noch etwas beispielcode drumrum den es für deine Zwecke ja nicht braucht.
Code:
TYPE "ANY_POINTER"
VERSION : 0.1
   STRUCT
      SyntaxID : Byte;
      Bereichstyp : Byte;
      Anzahl_Werte : Int;
      DB_Nr : Int;
      Startadresse : DWord;
   END_STRUCT;


END_TYPE


FUNCTION_BLOCK ANY_Test


TITLE = 'ANY_Test'




VERSION : '1.8'
AUTHOR  : VoR
NAME    : AV
FAMILY  : TUV


VAR_INPUT
    LS_PAR : ANY;  // Hier wird das Erste Wort aus dem LS DB aufgelegt
      pLS_PAR AT LS_PAR : ANY_POINTER;
END_VAR


VAR_OUTPUT
END_VAR


VAR_IN_OUT
END_VAR


VAR_TEMP
    byteadresse : INT;
    Bitadresse : INT;
    speicherbereich : WORD;
END_VAR


VAR
  END_VAR


CONST
END_CONST
                     
                     
(*Pointer auf UDT schreiben zum arbeiten*) // Ventilator allgemein
  pLS_PAR.SyntaxID := pLS_PAR.SyntaxID; // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
  pLS_PAR.Bereichstyp := pLS_PAR.Bereichstyp;   // Typ des Bereichs soll Byte sein (INT = 2)
  pLS_PAR.Anzahl_Werte := pLS_PAR.Anzahl_Werte; // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
  pLS_PAR.DB_NR := pLS_PAR.DB_NR; // Länge des Pointers weil wir einen Any ohne Länge angeben wollen
  pLS_PAR.Startadresse := pLS_PAR.Startadresse; // Länge des Pointers weil wir einen Any ohne Länge angeben wollen


    speicherbereich := DWORD_TO_word(SHR(in := pLS_PAR.Startadresse,n := 24));
    byteadresse := DWORD_TO_INT(SHR(in := SHL(in := pLS_PAR.Startadresse,n := 13), N := 16));
    bitadresse := DWORD_TO_INT(SHR(in := SHL(in := pLS_PAR.Startadresse,n := 29), N := 29));
    
    (*Hier wird der Pointer zurückgeschrieben*)
END_FUNCTION_BLOCK

Da es ANY aber z.B. in der S7-1200 nicht gibt ist man da dann so richtig aufgeschmissen wenn man die Nummer braucht. Z.B. für PEEK/POKE

mfG René
 
Darf ich mal fragen für was man die DB Nummer braucht? Mir fällt da gerade nichts ein?!

Gesendet von meinem SM-G930F mit Tapatalk
 
Darf ich mal fragen für was man die DB Nummer braucht? Mir fällt da gerade nichts ein?!

Gesendet von meinem SM-G930F mit Tapatalk

Oh da fällt mir viel ein... Fertige Bausteine von Fremdgeräten die nur absolut addressiert arbeiten z.B. Da muss mann dann selbst das Symbol irgendwie zerlegen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Spricht eigentlich etwas gegen diese Lösung?

Code:
VAR_INPUT 
      Quell_DB : DB_ANY;
      Ziel_DB : DB_ANY;
END_VAR


BEGIN
NETWORK
TITLE = 

      AUF #Quell_DB;
      L DBNO;
      T #T_DB_Quelle_INT;
 
      AUF #Ziel_DB;
      L DBNO;
      T #T_DB_Ziel_INT;
 
Zurück
Oben