ANY am PUT einer FC möglich?

C_H

Level-1
Beiträge
2
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
hallo,

ich hoffe ich bekomm ein bischen Klarheit darüber, ob man einen Standard-FC erstellen kann an dem man einen ANY-Zeiger als OUT ausgeben kann.

Ich hab folgendes Problem:
Ich möchte aus einem globalem Datenbaustein ( DB 90 in meinem Problem ) mit der SFC 20 BLKMOV Daten herausholen und in einem FB ( FB 8 ) verwenden. Da sich die Start-Adresse, wo ich die Daten aus dem DB heraushole ändert, habe ich mir dafür einen "dynamischen" ANY-Zeiger zusammengestzt, den ich dann an die SFC 20 angebunden hab und damit die Daten in den STAT-Teil des FB ( FB 8 ) kopiere. Soweit funktioiert das ganze schon ohne Probleme.:)
ABER:
Ich benötige jetzt den gleichen Ablauf in einem anderen FB auch, greif dort aber auf andere Daten aus einem anderen DB zu. Damit das ganze übersichtlich und verständlich wird, möchte ich nun eine FC erstellen in der ich mir den ANY-Zeiger zusammenstelle und über einen INOUT (oder OUT) zurückgebe um ihn nach dem FC-Aufruf an den SFC-Aufruf anbinden zu können. Ich möchte mir so einen Standard-Baustein erstellen, wo ich nur die Start-Adresse, die Länge und die DB-Nr. anbinde und ich den fertigen Zeiger zurückbekomme.
Das ganze funktioniert aber nicht so wie ich meine FC jetzt programmiert habe, da ich keinen ANY-Zeiger als INOUT oder OUT deklarieren kann.
Kann man überhaupt einen ANY-Zeiger zurückgeben? Oder kann man den Zeiger über das Arbeitsregister weiterverabeiten?:confused:

So hab ich meinen FC programmiert:
Ich kann aber keinen ANY-Zeiger als INOUT oder OUT deklarieren.

FUNCTION FC 55 : VOID
TITLE =ANY-Pointer DB zusammensetzen
AUTHOR : CH
VERSION : 0.1

VAR_INPUT
DB_NR : INT ; //DB-Nummer
Start_ADR : INT ; //Start-Adresse
Laenge : INT ; //Länge
END_VAR
VAR_TEMP
Temp_ANY_Pointer : ANY ; //ANY-Pointer
END_VAR
BEGIN
NETWORK
TITLE =

NETWORK
TITLE =Pointer zusammensetzen

LAR1 P##Temp_ANY_Pointer; // ANY-Pointer
L B#16#10; // Syntax ID
T LB [AR1,P#0.0];
L B#16#4; // Datentyp 4=Word
T LB [AR1,P#1.0];
L #Laenge; // Länge
T LW [AR1,P#2.0];
L #DB_NR; // DB-Nummer
T LW [AR1,P#4.0];
L P#DBX 0.0; // Speicherbereich Datenbaustein
L #Start_ADR; // Adresse des Datenbereiches
SLD 3; // In Pointerformat wandeln
+D ; // mit Bereichspointer verbinden
T LD [AR1,P#6.0];

END_FUNCTION


Danke schon für euere Hilfe!!!
 
Zuletzt bearbeitet:
Ich mach's so:

FUNCTION FC 74 : VOID
TITLE =
VERSION : 0.0

VAR_INPUT
Variable : ANY ;
END_VAR
VAR_OUTPUT
Zeiger : ANY ;
END_VAR
VAR_TEMP
Zwischenlager : ANY ;
END_VAR
BEGIN
NETWORK
TITLE =ANY-Zeiger auf die direkt angelegte Variable generieren
L P##Variable;
LAR1 ;
L W [AR1,P#0.0];
T LW 0;
L W [AR1,P#2.0];
T LW 2;
L W [AR1,P#4.0];
T LW 4;
L D [AR1,P#6.0];
T LD 6;
L P##Zeiger;
LAR1 ;
L LW 0;
T W [AR1,P#0.0];
L LW 2;
T W [AR1,P#2.0];
L LW 4;
T W [AR1,P#4.0];
L LD 6;
T W [AR1,P#6.0];
BE ;
END_FUNCTION

Man könnte latürnich mit Adressregister 2 arbeiten und den Umweg über Lokaldaten sparen. Aber das mit dem AR2 ist immer so 'ne Sache......

Netzwerk 4
U(
CALL "ANY_Generator"
Variable:=#SEND_DAT
Zeiger :=#ANY_Dummy
U BIE
)
SPBNB _002
L LW 2
T #SEND.LEN
_002: NOP 0


Und so verwende ich den Baustein z.B.: Der FC generiert den ANY-Zeiger auf SEND_DAT, da dieser im Lokaldatenbereich vorne anliegt, weiß ich daß in LW2 die Länge steht, die ich mir da raus hole und der Telegrammlänge des AG_SEND zuweise.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich habe mir einen FC geschrieben welcher für die Parametrierung eines Any-Pointers genutzt werden soll.
Nur leider klappt das mit der Übergabe der Parameter nicht so richtig.

FC: Bild im Anhang

Code im FC:
Code:
   L     P##Anypointer               //ANY-Pointer
      LAR1  
      L     #Sign                       //Signatur
      T     LB [AR1,P#0.0]
      L     #D_Typ                      //Datentyp
      T     LB [AR1,P#1.0]
      L     #W_Faktor                   //Anzahl blocks
      T     LW [AR1,P#2.0]
      L     #DB_Num                     //Quellnummer z.B. DB
      T     LW [AR1,P#4.0]
      L     #Start_Adr                  //Startadr.
      SLD   3
      T     LD [AR1,P#6.0]
      L     #Sp_Bereich                 //Typ des Speichers
      T     LB [AR1,P#6.0]

Ich übergebe also die entsprechenden Parameter an die Variable,
Var_output
Anypointer: Any;
end_Var
so weit so gut, easy.....

Am Aufruf des FC, leg ich an den "Ausgang" (AnyPointer) dan eine teporäre Variable "AnyP1" vom Typ any.
Hier liegt das Problem, die Parameter welche in die Variable "AnyPointer" übergeben werden, werden nicht weiter in die Variable "Anyp1" geleitet.

Ich hoffe auf Hilfe und das das Problem verstanden wurde?!

MfG
 

Anhänge

  • FC.png
    FC.png
    7,5 KB · Aufrufe: 38
genau dieses problem habe ich auch. ich möchte einen baustein schreiben, mit dem ich einen any-zeiger zusammensetzten kann und dann den "fertigen" zeiger zurückgeben kann und im aufrufenden baustein weiterverwenden kann z.b. beim aufruf von sfc20. aber die übergabe des any-zeigers an einen out-variable geht nicht. hab dafür noch keine lösung gefunden:confused:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe vor Monaten mit Hilfe von 2 Hans Berger Büchern so eine Funktion programmiert, allerdings noch nicht getestet.
Eventuell kann mir jemand im Gegenzug sagen, wie ich beim Antworten den Code so formatieren kann, damit er in einem Kasten wie oben erscheint.

Gruß

boogoo

code:
FUNCTION "Make_AnyPointer" : VOID
TITLE =AnyPonter für Datentypen zusammenstellen
//! Noch nicht getestet!
//Siehe: Automatisieren mit Step 7 in AWL und SCL, Hans Berger
//3. überarbeitete Auflage 2002 Seite 380
//4. überarbeitete Auflage 2004 Seite 414
AUTHOR : 'boogoo2000'
FAMILY : 'Pointer'
NAME : M_Any
VERSION : 0.1

VAR_INPUT
Typ : BYTE ; //Typ, Operantenbereich
Anzahl : INT ; //Anzahl
Datenbausteinnummer : INT ; //Danenbausteinnummer, sonst 16#0000
Operantenbereich : BYTE ; //Operantenbereich für Bereichszeiger, 10000ZZZ (siehe Buch) oder B#16#0
Byte_Adresse : INT ; //Byte-Adresse für Bereichszeiger
Bit_Adresse : INT ; //Bit-Adresse für Bereichszeiger
END_VAR
VAR_OUTPUT
AnyPonter : ANY ; //Anyponter als Ergebniss
END_VAR
VAR_TEMP
Bereichszeiger : DWORD ; //HM Bereichszeiger
END_VAR
BEGIN
NETWORK
TITLE =Zusammenstellung
L P##AnyPonter; // Adresse des AnyPointers
LAR1 ; // in AR1 legen
L B#16#10; // Syntax-ID in den
T LB [AR1,P#0.0]; // Any-Ponter eintragen
L #Typ; // Bereichstyp in de
T LB [AR1,P#1.0]; // Any-Ponter eintragen
L #Anzahl; // Anzahl in den
T LB [AR1,P#2.0]; // Any-Ponter eintragen
L #Operantenbereich; // Operandenbereich
SLD 24; //
L #Byte_Adresse; // Byte-Adresse
SLD 3; //
OD ; // und
L #Bit_Adresse; // Bit-Adresse
OD ; // in
T LB [AR1,P#6.0]; // Any-Ponter eintragen
SET ;
SAVE ;
END_FUNCTION
 
Ja das ist so weit auch in Ordnung.......
Darum gehts hier aber nicht.........
Sondern:
Bsp: Aufruf im Fb1

Code:
      CALL  "Make_AnyPointer"
       Typ      :=B#16#2                   
       Anzahl:=1                             
       W_Faktor  :=1
       DB_Num    :=303
       Operantenbereich:=85
       Byte_Adresse:=73
       Bit_Adresse   :=0
       AnyPointer:=#ANY_Ziel

Any_ziel ist eine Variable im FB1 vom Typ any.
Das Problem ist nun das Any_ziel nicht auf den Speicherbereich, wie AnyPointer zeigt. Die Parameter die im FC Make_AnyPointer festgelegt wurden, werden nicht in ANY_Ziel übernommen.

AnyPointer kann ja jeder parametrieren:twisted: **Scherz**

MfG
 
Hier ein FC mit SFC20 intern, Quelle und Ziel mussen beide eingegeven werden. Wenn sie diese beispiel gebrauchen wusten sie noch enige tekste van Niederlandisch nach Duits umzetsen.
Code:
FUNCTION FC 110 : INT
TITLE =Block copy met var. bron en var. doel.
//Kopieren van variable met een variable bron en een variabel doel.
//Bron en doel mogen elkaar niet overlappen
//Onderliggend bouwsteen SFC 20.
AUTHOR : JB
FAMILY : Kopie
NAME : Blk_mov
VERSION : 0.0
 
VAR_INPUT
  DB_NR_BRON : INT ; //0 =MERKER BEREIK ANDERS DB NR VAN BRON (Quelle)
  BYTE_1_BRON : INT ; //NR VAN EERSTE BYTE VAN BRON (Quelle)
  BYTE_WORD : BOOL ; //BYTE=0 WORD=1
  LENGTE : INT ; //AANTAL TE COPIEREN BYTES OF WOORDEN
  DB_NR_DOEL : INT ; //0 =MERKER BEREIK ANDERS DB NR VAN DOEL (Ziel)
  BYTE_1_DOEL : INT ; //NR VAN EERSTE BYTE VAN DOEL
END_VAR
VAR_TEMP
  T_AR1 : DWORD ; 
  T_ANY_BRON : ANY ; 
  T_ANY_DOEL : ANY ; 
END_VAR
BEGIN
NETWORK
TITLE =Opslaan inhoud van het Adresregister AR1
      TAR1  #T_AR1; 
NETWORK
TITLE =Samenstellen van DOEL adres in ANY formaat
      LAR1  P##T_ANY_BRON; //Beginadres ANY pointer in AR1 laden
      L     B#16#10; //Syntax-ID in de Any pointer zetten
      T     LB [AR1,P#0.0]; 
      L     B#16#2; //Bereichstyp BYTE laden
      UN    #BYTE_WORD; 
      SPB   Tran; 
      L     B#16#4; //Bereichstyp WORD laden
Tran: T     LB [AR1,P#1.0]; //BYTE of WORD in ANY pointer zetten
      L     #LENGTE; //Aantal BYTE'S of WORD'S
      T     LW [AR1,P#2.0]; //In ANY pointer zetten
      L     #DB_NR_BRON; //DB nr 
      T     LW [AR1,P#4.0]; //In ANY pointer zetten
      L     0; 
      ==I   ; 
      SPB   Merk; //Als DB nr = 0 dan naar merkers
      L     P#DBX 0.0; //Adres voor DBX 0.0
      SPA   Offs; 
Merk: L     P#M 0.0; //Adres voor M 0.0
Offs: L     #BYTE_1_BRON; //Nummer van eerste BYTE
      SLD   3; //Nummer op juiste plaats zetten
      +D    ; //Adres van 1ste BYTE of WORD
      T     LD [AR1,P#6.0]; //In ANY pointer zetten
NETWORK
TITLE =Samenstellen van BRON adres in ANY formaat
      LAR1  P##T_ANY_DOEL; //Beginadres ANY pointer in AR1 laden
      L     B#16#10; //Syntax-ID in de Any pointer zetten
      T     LB [AR1,P#0.0]; 
      L     B#16#2; //Bereichstyp BYTE laden
      UN    #BYTE_WORD; 
      SPB   Tra1; 
      L     B#16#4; 
Tra1: T     LB [AR1,P#1.0]; 
      L     #LENGTE; 
      T     LW [AR1,P#2.0]; 
      L     #DB_NR_DOEL; 
      T     LW [AR1,P#4.0]; 
      L     0; 
      ==I   ; 
      SPB   Mer1; 
      L     P#DBX 0.0; 
      SPA   Off1; 
Mer1: L     P#M 0.0; 
Off1: L     #BYTE_1_DOEL; 
      SLD   3; 
      +D    ; 
      T     LD [AR1,P#6.0]; 
NETWORK
TITLE =Oproep van SFC 20  (BLKMOV)
      CALL SFC   20 (
           SRCBLK                   := #T_ANY_BRON,//Adres waar data vandaan moet komen
           RET_VAL                  := #RET_VAL,//Foutmelding
           DSTBLK                   := #T_ANY_DOEL);//Adres waar data naartoe moet
NETWORK
TITLE =Inhoud adresregister AR1 terugzetten
      LAR1  #T_AR1; 
END_FUNCTION

Gruss,

Joop
 
ich möchte einen baustein schreiben, mit dem ich einen any-zeiger zusammensetzten kann und dann den "fertigen" zeiger zurückgeben kann und im aufrufenden baustein weiterverwenden kann z.b. beim aufruf von sfc20. aber die übergabe des any-zeigers an einen out-variable geht nicht.

Hier noch mal ein Programmbeispiel für einen ANY-Zeiger als OUT-Parameter an der Funkion FC110:

Code:
FUNCTION FC 110 : VOID
TITLE =ANY-ZEIGER
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : 'ANY'
VERSION : 1.0
 
VAR_INPUT
  SYNTAX_ID : BYTE ; 
  DATENTYP : BYTE ; 
  ANZAHL : WORD ; 
  DB_NUMMER : WORD ; 
  BEREICHSZEIGER : DWORD ; 
END_VAR
VAR_OUTPUT
  ANY_ZEIGER : ANY ; 
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ; 
  AR1_REGISTER : DWORD ; 
END_VAR
BEGIN
NETWORK
TITLE =DB-Register und Adressregister AR1 sichern
 
      L     DBNO; 
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; 
 
NETWORK
TITLE =ANY-ZEIGER
 
      L     P##ANY_ZEIGER; // ANY-Zeiger
      LAR1  ; 
 
      L     #SYNTAX_ID; // Syntax-ID
      T     B [AR1,P#0.0]; 
 
      L     #DATENTYP; // Datentyp
      T     B [AR1,P#1.0]; 
 
      L     #ANZAHL; // Anzahl
      T     W [AR1,P#2.0]; 
 
      L     #DB_NUMMER; // DB-Nummer
      T     W [AR1,P#4.0]; 
 
      L     #BEREICHSZEIGER; // Bereichszeiger
      T     D [AR1,P#6.0]; 
 
NETWORK
TITLE =DB-Register und Adressregister AR1 wiederherstellen
 
      AUF   DB [#DB_REGISTER]; 
 
      LAR1  #AR1_REGISTER; 
 
END_FUNCTION

Die mit der Funktion FC110 erzeugten ANY-Zeiger werden in der aufrufenden Funktion FC100 als IN- und OUT-Parameter an die Systemfunktion SFC20 übergeben:

Code:
FUNCTION FC 100 : VOID
TITLE =BLKMOV
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : 'ANY'
VERSION : 1.0
 
VAR_TEMP
  QUELLE_ANY_ZEIGER : ANY ; 
  ZIEL_ANY_ZEIGER : ANY ;   
  BLKMOV_RET_VAL : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =QUELLE (ANY-ZEIGER)
//QUELLE (ANY-ZEIGER)
//
//Syntax-ID      = B#16#10        = STEP 7
//Datentyp       = B#16#05        = INT
//Anzahl         = W#16#0A        = 10
//DB-Nummer      = W#16#C8        = DB200
//Bereichszeiger = DW#16#84000000 = DBX0.0
//   
 
      CALL FC   110 (
           SYNTAX_ID                := B#16#10,
           DATENTYP                 := B#16#5,
           ANZAHL                   := W#16#A,
           DB_NUMMER                := W#16#C8,
           BEREICHSZEIGER           := DW#16#84000000,
           ANY_ZEIGER               := #QUELLE_ANY_ZEIGER);
      NOP   0; 
 
NETWORK
TITLE =ZIEL (ANY-ZEIGER)
//ZIEL (ANY-ZEIGER)
//
//Syntax-ID      = B#16#10       = STEP 7
//Datentyp       = B#16#05       = INT
//Anzahl         = W#16#0A       = 10
//DB-Nummer      = W#16#C8       = DB200
//Bereichszeiger = DW16#840000A0 = DBX20.0
//   
 
      CALL FC   110 (
           SYNTAX_ID                := B#16#10,
           DATENTYP                 := B#16#5,
           ANZAHL                   := W#16#A,
           DB_NUMMER                := W#16#C8,
           BEREICHSZEIGER           := DW#16#840000A0,
           ANY_ZEIGER               := #ZIEL_ANY_ZEIGER);
      NOP   0; 
 
NETWORK
TITLE =QUELLE (ANY-ZEIGER) => ZIEL (ANY-ZEIGER)
 
      CALL SFC   20 (
           SRCBLK                   := #QUELLE_ANY_ZEIGER,
           RET_VAL                  := #BLKMOV_RET_VAL,
           DSTBLK                   := #ZIEL_ANY_ZEIGER);
      NOP   0; 
 
END_FUNCTION

Gruß Kai
 

Anhänge

  • FC100.pdf
    5,1 KB · Aufrufe: 36
  • FC110.pdf
    3,1 KB · Aufrufe: 28
  • DB200.pdf
    2,6 KB · Aufrufe: 20
  • VAT_1.jpg
    VAT_1.jpg
    271,8 KB · Aufrufe: 28
  • VAT_2.jpg
    VAT_2.jpg
    272 KB · Aufrufe: 20
Zuletzt bearbeitet:
Zurück
Oben