Step 7 Pointer zugriff temp Variable

EPaulo

Level-1
Beiträge
91
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,


Bis dato konnte ich mit P#DB407.DBX0.0 das ganze anbinden. Da ich nun den FB in meinen eigenen FB packen möchte muss ich die Anbindung über einen Eingang machen.
Hierzu muss ich nun den Eingang an den FB anbinden den ich integriert habe.
wie kann ich einen Pointer auf eine Temp Variable vom typ Any machen.
Die IN Variable hat die adresse 0.0 und ich würde gerne den Pointer auf 0.0 machen.

Danke im Voraus
 
Nochmal von vorne ... was willst du machen ?
Du hast an deinem FB einen IN-Parameter vom Typ ANY - an den willst du eine Temp-Variable übergeben ?

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Larry,

geb zu etwas unglücklich geschrieben.
Also, ich habe einen Baustein den ich bis jetzt Parametriert habe mit
P#DB407.DBX0.0
Nun integriere ich diesen Baustein in meinen FB, und möchte eine IN Variable machen in der ich das ganze durchreiche.
Also an meiner IN Variable vom Typ ANY möchte ich Später mein P#DB407.DBX0.0 anparametrieren und intern möchte ich die IN variable an den Baustein anlegen.
Meine In Variable hat aktuell die adresse 0.0

Ist es jetzt etwas verständlicher?

Gruß
 
Bist Du sicher, daß der IN-Parameter vom Typ ANY ist? "P#DB407.DBX0.0" ist kein ANY sondern ein POINTER

Da Dein neuer FB auf jeden Fall "multiinstanzfähig" sein muß ist es uninteressant an welcher Adresse der IN-Parameter liegt. Du mußt Dich auf den Name des IN-Parameters beziehen - wie heißt der? Wie heißt der IN-Parameter des integrierten FB?

Programmierst Du in SCL oder AWL?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zusammengesetzte Datentypen kann man nicht direkt von den Bausteinparametern an aufzurufende Bausteine durchreichen. Sie müssen zunächst in TEMP- oder STAT-Variablen umkopiert werden, welche dann als Aktualparameter an die aufzurufenden Bausteine gegeben werden können.

Zum Umkopieren von zusammengesetzten Datentypen aus Bausteinparametern kann man in AWL nicht BLKMOV verwenden (weil man ja den zusammengesetzten Datentyp nicht an die SFC weiterreichen kann), sondern man muß mit elementaren Anweisungen zwischen Speicher-Adressen kopieren. In AWL ist die vollsymbolische Referenzierung von Strukturmembern nicht möglich, man kann nur die Anfangsadresse der Struktur referenzieren und muß dann die Adress-Offsets der Strukturmember absolut hinzuaddieren. Zusätzlich ist die Adressberechnung in FB-Multiinstanzen nicht ganz einfach. Die Adressberechnung ist fehlerträchtig und relativ unverständlich, in AWL passt sich die absolute Berechnung bei Strukturänderungen nicht automatisch an. Deshalb überläßt man die korrekte Adressberechnung am besten einem Compiler und schreibt den Quellcode z.B. in SCL. Der Compiler übersetzt das dann fehlerfrei (in mehr oder weniger effizienten Code). Bei SCL hat man sogar noch den Vorteil, daß man sich um das Umkopieren von den Bausteinparametern über TEMP nicht kümmern muß, das erledigt der SCL-Compiler im Hintergrund automatisch mit.

Durchreichen des ANY-Aktualparameters an den Unter-FB in AWL:
Code:
[COLOR="#008000"]//AR2 (Multiinstanzoffset) sichern, weil AR2 hier verändert wird[/COLOR]
      TAR2  #AR2_Save                   [COLOR="#008000"]//(DWord in TEMP)[/COLOR]

[COLOR="#008000"]//AR1 auf Adresse des #IN_ANY setzen[/COLOR]
      L     P##IN_ANY                   [COLOR="#008000"]//(DI) Adresse des IN_ANY in dieser FB-Instanz[/COLOR]
      TAR2                              [COLOR="#008000"]//Offset falls dieser FB als Multiinstanz aufgerufen wird[/COLOR]
      UD    DW#16#FFFFFF                [COLOR="#008000"]// Bereichskennung (DB) ausblenden[/COLOR]
      +D
      LAR1                              [COLOR="#008000"]//AR1: Adresse #IN_ANY im IDB[/COLOR]

[COLOR="#008000"]//AR2 auf Adresse des #Unter_FB_Instanz_1.IN_ANY setzen[/COLOR]
[COLOR="#008000"]//      L   P##Unter_FB_Instanz_1.IN_ANY //das geht leider nicht! --> manuell zusammenaddieren[/COLOR]
      L     P##Unter_FB_Instanz_1       [COLOR="#008000"]//(DI) Anfangsadresse der eingebetteten FB-Instanz in dieser FB-Instanz[/COLOR]
      L     [COLOR="#FF0000"]P#0.0[/COLOR]                       [COLOR="#008000"]//<-- hier manuell den Offset von IN_ANY im Unter-FB eintragen![/COLOR]
      +D
      TAR2                              [COLOR="#008000"]//Offset falls dieser FB als Multiinstanz aufgerufen wird[/COLOR]
      UD    DW#16#FFFFFF                [COLOR="#008000"]// Bereichskennung (DB) ausblenden[/COLOR]
      +D
      LAR2                              [COLOR="#008000"]//AR2: Adresse #Unter_FB_Instanz_1.IN_ANY im IDB[/COLOR]

[COLOR="#008000"]//den ANY-Aktualparameter von #IN_ANY nach #Unter_FB_Instanz_1.IN_ANY kopieren[/COLOR]
[COLOR="#008000"]//quasi *[IDB].[AR1] --> *[IDB].[AR2] [/COLOR]
      L     DID [AR1,P#0.0]             [COLOR="#008000"]//ANY: Kennung + Typ + Länge[/COLOR]
      T     DID [AR2,P#0.0]
      L     DIW [AR1,P#4.0]             [COLOR="#008000"]//ANY: DB-Nummer[/COLOR]
      T     DIW [AR2,P#4.0]
      L     DID [AR1,P#6.0]             [COLOR="#008000"]//ANY: Bereichsadresse[/COLOR]
      T     DID [AR2,P#6.0]

[COLOR="#008000"]//AR2 wiederherstellen vor Zugriff auf Instanzvariablen und Unter-Instanzen![/COLOR]
      LAR2  #AR2_Save

[COLOR="#008000"]//Unter-FB-Instanz aufrufen, dabei IN_ANY nicht beschalten (der Aktualparameter wurde kopiert)[/COLOR]
      CALL  #Unter_FB_Instanz_1
       IN_ANY  :=

Harald
 
P#DB407.DBX0.0 als Parameter übergeben.

Inbetriebnehmer und Servicetechniker werden dich verfluchen. Zurecht!!!

Bitte Finger von sowas lassen, ausser es dient den KnowHow-Schutz!!!

Das ist im Querverweis nie mehr zu finden!!!

Besser.

DB per BlockDB-Parameter übergeben.
Wenn es sein muss, dann Startadresse als Wert.

Im FB dann zur Zugriffsadresse zusammensetzen.

Der Service wird's dir danken!

 
:confused:
Verwechselst Du da was? "P#DB407.DBX0.0" (ein POINTER) oder z.B. "P#DB407.DBX0.0 BYTE 10" (ein ANY) ist super gut in den Querverweisen zu finden.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hier noch eine bessere Variante, die ohne das manuelle Eintragen eines Speicheroffsets auskommt und sich dadurch an FB/Strukturänderungen automatisch anpasst. Zwar wird der ANY-Aktualwert dabei zweimal kopiert (IN_ANY --> Temp_ANY --> Unter_FB_Instanz_1.IN_ANY) doch der Code wird kürzer und auch verständlicher. Die problematische Adressberechnung P##Unter_FB_Instanz_1.IN_ANY wird dabei dem AWL-Compiler überlassen.

Durchreichen des ANY-Aktualparameters an den Unter-FB via ANY-Variable in TEMP in AWL:
Code:
[COLOR="#008000"]//AR2 (Multiinstanzoffset) sichern, weil AR2 hier verändert wird[/COLOR]
      TAR2  #AR2_Save                   [COLOR="#008000"]//(DWord in TEMP)[/COLOR]

[COLOR="#008000"]//AR1 auf Adresse des #IN_ANY setzen[/COLOR]
      L     P##IN_ANY                   [COLOR="#008000"]//(DI) Adresse des IN_ANY in dieser FB-Instanz[/COLOR]
      TAR2                              [COLOR="#008000"]//Offset falls dieser FB als Multiinstanz aufgerufen wird[/COLOR]
      UD    DW#16#FFFFFF                [COLOR="#008000"]// Bereichskennung (DB) ausblenden[/COLOR]
      +D
      LAR1                              [COLOR="#008000"]//AR1: Adresse #IN_ANY im IDB[/COLOR]

[COLOR="#008000"]//AR2 auf Adresse des #Temp_ANY setzen[/COLOR]
      LAR2  P##Temp_ANY                 [COLOR="#008000"]//AR2: Adresse #Temp_ANY in TEMP[/COLOR]

[COLOR="#008000"]//den ANY-Aktualparameter von #IN_ANY nach #Temp_ANY kopieren[/COLOR]
[COLOR="#008000"]//quasi *[IDB].[AR1] --> *[AR2][/COLOR]
      L     DID [AR1,P#0.0]             [COLOR="#008000"]//ANY: Kennung + Typ + Länge[/COLOR]
      T     LD  [AR2,P#0.0]
      L     DIW [AR1,P#4.0]             [COLOR="#008000"]//ANY: DB-Nummer[/COLOR]
      T     LW  [AR2,P#4.0]
      L     DID [AR1,P#6.0]             [COLOR="#008000"]//ANY: Bereichsadresse[/COLOR]
      T     LD  [AR2,P#6.0]

[COLOR="#008000"]//AR2 wiederherstellen vor Zugriff auf Instanzvariablen und Unter-Instanzen![/COLOR]
      LAR2  #AR2_Save

[COLOR="#008000"]//Unter-FB-Instanz aufrufen[/COLOR]
      CALL  #Unter_FB_Instanz_1
       IN_ANY  :=#Temp_ANY

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
P#DB407.DBX0.0 als Parameter übergeben.

Inbetriebnehmer und Servicetechniker werden dich verfluchen. Zurecht!!!

Bitte Finger von sowas lassen, ausser es dient den KnowHow-Schutz!!!

Das ist im Querverweis nie mehr zu finden!!!

Besser.

DB per BlockDB-Parameter übergeben.
Wenn es sein muss, dann Startadresse als Wert.

Im FB dann zur Zugriffsadresse zusammensetzen.

Der Service wird's dir danken!



Gibt es für die Zusammensetzung eines ANY-POINTERS hier im Forum auch schon Ansätze bzw. Beispiele?
Ich habe sie bisher noch nicht gefunden.


Grüße
 
Gibt es für die Zusammensetzung eines ANY-POINTERS hier im Forum auch schon Ansätze bzw. Beispiele?
Ich habe sie bisher noch nicht gefunden.

Zusammensetzung von ANY findet man in der Step7 Hilfe
Simatic Manger -> Hilfe, ANY eingeben "Format des Parametertyps ANY" auswählen

hier zwei Bausteine von mir, CreateANY (ANY zusammenbauen), SplitANY (ANY auseinandernehmen)

Code:
FUNCTION "m7a_CreateANY" : VOID
TITLE =CreateANY: erzeugt ANY aus Einzelbestandteilen
//Codierung Datentyp:
//00h : NIL  : Nullpointer
//01h : BOOL : Bits
//02h : BYTE 
//03h : CHAR
//04h : WORD
//05h : INT
//06h : DWORD
//07h : DINT
//08h : REAL
//09h : DATE
//0Ah : Time_OF_DAY (TOD)
//0Bh : TIME
//0Ch : S5Time
//0Dh : nicht definiert
//0Eh : DATE_AND_TIME (DT)
//13h : STRING
//
//Codierung Speicherbereich:
//80h : P : Peripherie
//81h : E : Eingänge
//82h : A : Ausgänge
//83h : M : Merker
//84h : DB: Datenbaustein
//85h : DI: Instanzdatenbaustein
//86h : L : Lokaldaten (L-Stack)
//87h : V : voriger Lokaldatenstack
//
//AUTOR: Stefan Maag 
//DATUM: 10/2007
//
//AENDERUNGSVERMERKE:
//--------------------------------------------------------------------------------
//DATUM        NAME       AENDERUNG
//--------------------------------------------------------------------------------
//04.11.2011   S.Maag     Fehler Speicherbereichsverarbeitung mit UD statt OD
//                        behoben
//--------------------------------------------------------------------------------
//
//HINWEISE:
AUTHOR : 'S.Maag'
FAMILY : Maagic7
VERSION : 0.1


VAR_INPUT
  B1_DataType : BYTE ;    //1=Bool 2=Byte 3=Char 4=Word 5=INT 6=DW 7=DINT 8=Real 9=Date ...
  B23_Wiederholung : INT ;    //Wiederholungsfaktor
  B45_DB : INT ;    //DB-Nummer oder 0
  B6_Speicher : BYTE ;    //Hex 80=P 81=E 82=A 83=M 84=DB 85=DI 86=L 87=V
  ByteAdr : INT ;    //ByteAdresse
  BitAdr : INT ;    //Bitadresse 0..7
END_VAR
VAR_OUTPUT
  AnyPointer : ANY ;    
END_VAR
VAR_TEMP
  pBit : DWORD ;    
  AR1 : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =

      L     P##AnyPointer; 
      LAR1  ; 
// Byte 0 enthält immer 10h für S7
      L     B#16#10; 
      T     B [AR1,P#0.0]; 

      L     #B1_DataType; 
      T     B [AR1,P#1.0]; // Byte 1 = Datentyp

      L     #B23_Wiederholung; 
      T     W [AR1,P#2.0]; // Byte 2&3 = Wiederholungsfaktor

      L     #B45_DB; 
      T     W [AR1,P#4.0]; // Byte 4&5 = Datenbaustein-Nr

      L     #BitAdr; 
      L     B#16#7; // Bitadresse auf 3 Bit Begrenzen 0..7
      UW    ; 
      L     #ByteAdr; // ByteAdresse um 3 nach links => Pointerformat
      SLD   3; 
      OD    ; // ByteAdress und Bitadresse verbinden
      T     D [AR1,P#6.0]; 

      L     #B6_Speicher; 
      T     B [AR1,P#6.0]; // Byte 6 = Speicherbereich

      SET   ; 
      SAVE  ; 
      CLR   ; 
END_FUNCTION

FUNCTION "m7a_SplitAny" : VOID
TITLE =SplitAny : Zerteilt ANY-Pointer in die relevanten Bestandteile
//Codierung Datentyp:
//00h : NIL  : Nullpointer
//01h : BOOL : Bits
//02h : BYTE 
//03h : CHAR
//04h : WORD
//05h : INT
//06h : DWORD
//07h : DINT
//08h : REAL
//09h : DATE
//0Ah : Time_OF_DAY (TOD)
//0Bh : TIME
//0Ch : S5Time
//0Dh : nicht definiert
//0Eh : DATE_AND_TIME (DT)
//13h : STRING
//
//Codierung Speicherbereich:
//80h : P : Peripherie
//81h : E : Eingänge
//82h : A : Ausgänge
//83h : M : Merker
//84h : DB: Datenbaustein
//85h : DI: Instanzdatenbaustein
//86h : L : Lokaldaten (L-Stack)
//87h : V : voriger Lokaldatenstack
//
//AUTOR: Stefan Maag 
//DATUM: 10/2007
//
//AENDERUNGSVERMERKE:
//--------------------------------------------------------------------------------
//DATUM        NAME            AENDERUNG
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
//
//HINWEISE:
AUTHOR : 'S.Maag'
FAMILY : Maagic7
VERSION : 0.1


VAR_INPUT
  AnyPointer : ANY ;    
END_VAR
VAR_OUTPUT
  B1_DataType : BYTE ;    
  B23_Wiederholung : INT ;    
  B45_DB : INT ;    
  B6_Speicher : BYTE ;    
  ByteAdr : INT ;    
  BitAdr : INT ;    
END_VAR
VAR_TEMP
  AR1 : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =

      TAR1  #AR1; // Adressregister 1 sichern

      L     P##AnyPointer; 
      LAR1  ; 
// Byte 0 enthält immer 10h für S7, daher nicht ausgeben
// L     B [AR1,P#0.0]
// T     #B0_PLC

      L     B [AR1,P#1.0]; // Byte 1 = Datentyp
      T     #B1_DataType; 

      L     W [AR1,P#2.0]; // Byte 2&3 = Wiederholungsfaktor
      T     #B23_Wiederholung; 

      L     W [AR1,P#4.0]; // Byte 4&5 = Datenbaustein-Nr
      T     #B45_DB; 

      L     B [AR1,P#6.0]; // Byte 6 = Speicherbereich
      T     #B6_Speicher; 

      L     D [AR1,P#6.0]; // Byte 7&8&9 = BitPointer
      SRD   3; // daraus ByteAdresse berechnen
      T     #ByteAdr; 

      L     B [AR1,P#9.0]; // Byte 9, Bit 0..2 = Bitadresse 
      L     B#16#7; 
      UW    ; 
      T     #BitAdr; 

      LAR1  #AR1; // ursprüngliches Adressregister 1 herstellen
      SET   ; 
      SAVE  ; 
      CLR   ; 
END_FUNCTION
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Maagic7

soweit komme ich meinem Ziel näher
Ich habe 2 Strukturen und ein ANY das ich senden möchte.
Also gehe ich wie folgt vor.
Ich lade mein ANY in den AR
Kopiere meine Kopfdaten alle in den AR1 ab Byte 0
Nun kommt mein Problem wo ich nicht weiter weiß

An meinem Baustein lege ich ein ANY an.
Da Stehet drin z.B. P#DB308.dbx0.0 10BYTE, das steht dann in meinem IN ANY
Wie setzet ich jetzt dieses ANY an mein bereits vorhandenes Lokales ANY an.
Eigentlich könnte ich den Block Move nehmen, aber wie muss die Ausgangsvariable aussehen am Block move
Meine Lokale ANY Variable heißt SENDDATA und ist bis BYTE 60 gefüllt also will ich die Daten ab Byte 61 einfügen, müsse das dann am DESTBLK ansehen? P##SENDDATE????
Oder Soll ich sie besser mit AWL einsetzen, wie müsste dann der AWL befehle aussehen?
Und sind alle Informationen die ich aussen am IN ANY angelegt habe dann in meiner IN ANY Variable enthalten?
Danke im Voraus
 
Zuletzt bearbeitet:
eigentlich komme ich zum Entschluss das es garnicht geht wie ich mir das vorstelle.
Die Lösung kann eigentlich nur sein das ich in Miene Struktur einen SEND Data beriech vorhalte von z.B. 100BYTE und nun die Daten vom IN ANY in meine Reservierten Bereich kopiere und wenn es mehr sind wie 100BYTE muss ich halt 2x senden? Oder wie seht ihr das? Gibt es einen einfacheren weg?
 
Hi Epaulo,

du kannst deinen IN_Any nicht direkt im Programm verwenden weil du nicht den ANY sondern einen Pointer auf den ANY übergibst. In diesem Thread gab es aber schon mehrere Beispiele, wie man das Lösen bzw. umgehen kann..
Wenn ich das richtig verstehe, willst du 10 Byte von einem Any an ein anderes Any "einfügen". Dazu musst du den einzufügenden Any auseinanderflücken und die Addresse bestimmen wo das 61te Byte liegt und dann per Blockmove die 10 Byte in den tatsächlichen DB des 2ten Any transferieren.

mfg Clyde
 
Zurück
Oben