SCL Frage

s7Opa

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

kann mir jemand helfen? Warum funktioniert der SCL Code nicht mit dem FILL? Beim BLKMOV ist das kein Problem. Danke

Code:
FUNCTION UDF_Fill_TypeToDB: BOOL  
TITLE = 'Fill DB Range with Type'
//Author...: RWo 06.03.12
VERSION : '1.0'
AUTHOR  : RWo
NAME    : DBtoTyp
FAMILY  : RWo_LIB
KNOW_HOW_PROTECT
VAR_INPUT
  Source:     ANY;  //target pointer (Any)
  //Source_DB:  INT;  //source data block
  //Source_BY:  INT;  //source start byte
  //Target:     ANY;  //target pointer (Any)
  Target_DB:  INT;  //
  Target_BY:  INT;  //
  ByteCount:  INT;  //number of byte to copy
END_VAR
VAR_IN_OUT
END_VAR
VAR_OUTPUT
  //SourceObj:  INT;  //Source object
  //SourceVal:  INT;  //source value
  //TargetObj:  INT;  //Target object
  //TargetVal:  INT;  //target value 
END_VAR
VAR_TEMP
  RET_V:  INT;
  QUELLE: ANY;
  ZIEL:   ANY;
  (*
  //Wir basteln uns einen Any Pointer für die Quelle .....................................
  sQuell AT QUELLE :STRUCT
    S7BYTE :BYTE;   // Byte 0       Reserviert für S7 (10h)
    DatTyp :BYTE;   // Byte 1       Datentyp *1
    Anzahl :INT;    // Byte 2+3     Länge der Variablen
    DBNR   :INT;    // Byte 4+5     DB-Nummer
    //SpBer1 :BYTE;   // Byte 6       Datentyp beim Auslesen *3 (Speicherbereich *2)
    //Null   :BYTE;   // Byte 7       Null beim Auslesen
    //SpBer2 :WORD;   // Byte 8+9     Speicherbereich Nummer beim Auslesen *3
    Zeiger :DWORD;  // Byte 6+7+8+9 Bereichszeiger_DW OR Adressword_DW (ShiftLinks 3)
  END_STRUCT;
  *)
  //Wir basteln uns einen Any Pointer für das Ziel .......................................
  sZiel AT ZIEL :STRUCT
    S7BYTE :BYTE;   // Byte 0       Reserviert für S7 (10h)
    DatTyp :BYTE;   // Byte 1       Datentyp *1
    Anzahl :INT;    // Byte 2+3     Länge der Variablen
    DBNR   :INT;    // Byte 4+5     DB-Nummer
    //SpBer1 :BYTE;   // Byte 6       Datentyp beim Auslesen *3 (Speicherbereich *2)
    //Null   :BYTE;   // Byte 7       Null beim Auslesen
    //SpBer2 :WORD;   // Byte 8+9     Speicherbereich Nummer beim Auslesen *3
    Zeiger :DWORD;  // Byte 6+7+8+9 Bereichszeiger_DW OR Adressword_DW (ShiftLinks 3)
  END_STRUCT;  

  (* ===================================================================================== 
   *1) Codierung der Datentypen ----------------------------------------------------------
    Hexadezimalcode Datentyp    Beschreibung
    b#16#00         NIL         Nullpointer
    b#16#01         BOOL        Bits
    b#16#02         BYTE        Bytes (8 Bits)
    b#16#03         CHAR        Zeichen (8 Bits)
    b#16#04         WORD        Wörter (16 Bits)
    b#16#05         INT         Ganzzahlen (16 Bits)
    b#16#06         DWORD       Wörter (32 Bits)
    b#16#07         DINT        Ganzzahlen (32 Bits)
    b#16#08         REAL        Gleitpunktzahlen (32 Bits)
    b#16#09         DATE        Datum
    b#16#0A         TIME_OF_DAY (TOD) Uhrzeit
    b#16#0B         TIME        Zeit
    b#16#0C         S5TIME      Datentyp S5TIME
    b#16#0E         DATE_AND_TIME (DT)Datum und Zeit (64 Bits)
    b#16#13         STRING      Zeichenkette
   *2) Codierung der Speicherbereiche ----------------------------------------------------
    Hexadezimalcode Bereich     Beschreibung
    b#16#80         P           Speicherbereich der Peripherie
    b#16#81         E           Speicherbereich der Eingänge
    b#16#82         A           Speicherbereich der Ausgänge
    b#16#83         M           Speicherbereich der Merker
    b#16#84         DB          Datenbaustein
    b#16#85         DI          Instanz-Datenbaustein
    b#16#86         L           Lokaldaten (L-Stack)
    b#16#87         V           Vorherige Lokaldaten
   *3) ANY-Format bei Parametertypen (zum auslesen von Information) ----------------------
    Hexadezimalcode Datentyp    Beschreibung
    b#16#17         BLOCK_FB    FB-Nummer
    b#16#18         BLOCK_FC    FC-Nummer
    b#16#19         BLOCK_DB    DB-Nummer
    b#16#1A         BLOCK_SDB   SDB-Nummer
    b#16#1C         COUNTER     Nummer des Zählers
    b#16#1D         TIMER       Nummer der Zeit
  ===================================================================================== *)
END_VAR

BEGIN
//Init
//----------------------------------------------------------------------------------------
  OK := TRUE; RET_V := 0; 
  (*
  //Zusammenstellen des Quellpointers
  sQuell.S7BYTE    := B#16#10;
  sQuell.DatTyp    := B#16#02;
  sQuell.Anzahl    := ByteCount;
  sQuell.DBNR      := Source_DB;
  //sQuell.Null      := B#16#0;
  sQuell.Zeiger    := DW#16#84000000 OR SHL (IN:= INT_TO_DWORD(Source_BY), N:=3); //eintragen
  *)
  //Zusammenstellen des Zielpointers
  sZiel.S7BYTE   := B#16#10;
  sZiel.DatTyp   := B#16#02;
  sZiel.Anzahl   := ByteCount;
  sZiel.DBNR     := Target_DB;
  //sZiel.Null     := B#16#0;
  sZiel.Zeiger   := DW#16#84000000 OR SHL (IN:= INT_TO_DWORD(Target_BY), N:=3); //eintragen
  
  //direktes kopieren des ANY Pointers
  QUELLE := Source;
  //ZIEL := Target;
  
//----------------------------------------------------------------------------------------
//Programm
//----------------------------------------------------------------------------------------
  // Aufruf des SFC 20 fürs kopieren
  //RET_V := BLKMOV(SRCBLK := QUELLE ,DSTBLK := ZIEL);
  
  // Aufruf des SFC 21 fürs füllen  
  RET_V := FILL(BVAL := QUELLE, BLK := ZIEL);
            
  //Auslesen
  //SourceObj   := VON.SpBer1
  //SourceVal   := VON.SpBer2;
  //TargetObj   := NACH.SpBer1;
  //TargetVal   := NACH.SpBer2;

//END ------------------------------------------------------------------------------
  IF RET_V <> 0 OR NOT OK THEN 
    UDF_Fill_TypeToDB := TRUE; 
  ELSE 
    UDF_Fill_TypeToDB := FALSE; 
  END_IF; 
  OK:=TRUE;
END_FUNCTION
 
-32478 ist der Fehlercode. Aufgerufen wird der FC in einem FB, die Quelle ist ein INT, das Ziel ist ein Bereich über mehrere Strukturen.

Code:
      CALL  "FILL"
       BVAL   :=#t.iZERO
       RET_VAL:=#t.iRETVAL
       BLK    :=P#DB3213.DBX250.0 BYTE 106

Rufe ich den Fill direkt auf gehts. Die Parameter sind gleich...
 
Zuletzt bearbeitet:
Wenn #t.iZERO eine Temp-Variable ist, dann ist die Bereichskennung DB (0x84) aber falsch die du dort eincodierst.

8x22 sagt "Bereichslängenfehler beim Lesen eines Parameters"
 
...ahhh ich habs. Du warst nah dran. Der ANY für die Quelle muß auf eine double zeigen.


(verdammte Filed PG Tastatur=
 
Zuletzt bearbeitet:
Der Parametertyp von BVAL ist aber ANY. Du kannst da zwar direkt eine Variable dranschreiben, ist und bleibt aber immer noch ein Any.
Bzw. wahrscheinlich verbirgt dir der AWL-Editor, dass er daraus im Hintergrund einen Any-Zeiger bastelt.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...ach was. Das scheint mir eher mit dem Aufruf bzw. bei der ANY-Übergabe des SFC21 in SCL zu liegen. Denn, nochmal, beim direkten Aufruf gehts.

8x22 sagt "Bereichslängenfehler beim Lesen eines Parameters"
Deine Fehlerbeschreibung war der Zünder...
 
Zuletzt bearbeitet:
Du musst es mir ja nicht glauben wenn du nicht willst, es ist aber so. Der Parametertyp ist ANY.
Du baust dir selber einen Bereichszeiger mit einer höchstwahrscheinlich falschen Bereichskennung, ob es so ist lässt sich nur definitiv sagen wenn wir auch den Bausteinaufruf und die Schnittstelle sehen. Für den SFC intern wären das bei deiner Konstruktion (der Parameter ist Variable im Temp-Bereich) imho die Vor-Vor-Vorgängerlokaldaten, und das geht nicht.
 
Zurück
Oben