SFC 20 Problem

Felse

Level-1
Beiträge
221
Reaktionspunkte
10
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
ich weiß das Thema wurde schon oft behandelt, aber trotzdem. Hab ein Programm vor mir und werd einfach nicht schlau daraus. Der SFC 20 wird verwendet um Daten zu speichern und zu laden. Das Laden funktioniert auch, beim Speichern bekomm ich allerdings den Fehlercode 837F und die Daten werden nicht überschrieben... Die Hilfe sagt dazu: 8x7F "interner Fehler am Parameter X". Ist nun der Fehler an der 3. Variable dich kopiert wird oder was und wie kann ich dass beheben?
Bitte helft mir ich bin für jede Hilfe dankbar.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sorry. Hier ist was. Hab leider nicht so den Plan von AWL. Das angehangene Bild zeigt die Daten die sich nicht überschreiben lassen.


Code:
NW14 Daten lesen
 
   U     "Prg_wahl".PRG_EDIT_SELECT.load
      SPBN  b998
// vom  richtigen DB an der richtige Stelle werden die Daten ausgelesen und 
//  in DB90 zwischengespeichert
      CALL  "copy auf ziel"
       SRC_DB  :=#DB_NR
       SRC_Byte:=#AKT_Byte
       SRC_Typ :=FALSE
       SRC_Len :=16
       DEST_Any:="FRG_HEIZ_KÜHL".VISU_AKT_SCHRITT
       RET_VAL :=MW16
b998: NOP   0

Code:
NW 15 Daten schreiben
 
  U     "Prg_wahl".PRG_EDIT_SELECT.save
      SPBN  b999
// vom DB90 wird die Daten nun in den richtigen DB(101-110) an die richtige Stelle geschrieben
      CALL  "copy von quelle"
       DEST_DB  :=#DB_NR
       DEST_Byte:=#AKT_Byte
       DEST_Typ :=FALSE
       DEST_Len :=16
       SRC_Any  :="FRG_HEIZ_KÜHL".VISU_AKT_SCHRITT
       RET_VAL  :=MW16
b999: NOP   0
 

Anhänge

  • DB.bmp
    420,8 KB · Aufrufe: 19
Hier ist noch was.


fürs Lesen:
Code:
 TAR1  #T_AR1
 TAR2  #T_AR2
 
 
 LAR1  P##T_SRC_Any                // Anfangsadresse des Quell-Any-Pointers in AR1 laden
      L     B#16#10                     // Syntax-ID in den Any-Pointer eintragen
      T     LB [AR1,P#0.0]
      L     B#16#2                      // Bereichstyp BYTE laden
      UN    #SRC_Typ                    // wenn BYTE gewählt wurde, dann Sprung zum Eintrag
      SPB   Tran
      L     B#16#4                      // sonst Bereichstyp WORD laden
Tran: T     LB [AR1,P#1.0]              // und im Any-Pointer ablegen
      L     #SRC_Len                    // Anzahl der zu übertragenden Bytes/Worte eintragen
      T     LW [AR1,P#2.0]
      L     #SRC_DB                     // Quell-DB-Nummer eintragen
      T     LW [AR1,P#4.0]
      L     0                           // wenn Quell-DB-Nummer = 0 dann
// wird aus dem Merkerbereich 
      ==I                               // übertragen, sonst aus einem DB
      SPB   Merk
      L     P#DBX 0.0                   // Bereichspointer in Datenbaustein laden
      SPA   Offs
Merk: L     P#M 0.0                     // Bereichspointer in Merkerbereich laden
Offs: L     #SRC_Byte                   // Nummer des 1. zu kopierenden Bytes laden
      SLD   3                           // in Pointerformat wandeln
      +D                                // zum Bereichspointer addieren
      T     LD [AR1,P#6.0]              // Ergebnis in ANY-Ptr eintragen

  L     P##DEST_Any                 // Adr des Any-Ptr in AR1 legen
      LAR1  
      L     B#16#2                      // ist der Bereichstyp des übergebenen Any-Pointers
      L     B [AR1,P#1.0]               // = Byte oder = Word, erfolgt der Sprung
      ==I   
      O(    
      L     B#16#4
      ==I   
      )     
      SPB   Copy
      L     W#16#80FF                   // ansonsten Fehlerkennung laden
      T     #RET_VAL                    // an den Aufrufer übergeben
      SPA   Ende                        // Bausteinbearbeitung beenden
Copy: LAR2  P##T_DEST_Any               // Adr. des temp. Any-Ptr laden
      L     5                           // 5 Worte müssen kopiert werden
Back: T     #Count
      L     W [AR1,P#0.0]               // Umlegung des Any-Pointers als Inputvariable in
      T     LW [AR2,P#0.0]              // die Lokaldaten
      +AR1  P#2.0
      +AR2  P#2.0
      L     #Count
      LOOP  Back


CALL  "BLKMOV"
       SRCBLK :=#T_SRC_Any
       RET_VAL:=#SFC_Ret_Val
       DSTBLK :=#T_DEST_Any
 
 
  L     #SFC_Ret_Val
  T     #RET_VAL
 
 
Ende: LAR1  #T_AR1
         LAR2  #T_AR2

fürs Schreiben:

Code:
 TAR1  #T_AR1
 TAR2  #T_AR2
 
  LAR1  P##T_DEST_Any               // Anfangsadresse des Quell-Any-Pointers in AR1 laden
      L     B#16#0                      // Syntax-ID in den Any-Pointer eintragen
      T     LB [AR1,P#0.0]
      L     B#16#2                      // Bereichstyp BYTE laden
      UN    #DEST_Typ                   // wenn BYTE gewählt wurde, dann Sprung zum Eintrag
      SPB   Tran
      L     B#16#4                      // sonst Bereichstyp WORD laden
Tran: T     LB [AR1,P#1.0]              // und im Any-Pointer ablegen
      L     #DEST_Len                   // Anzahl der zu übertragenden Bytes/Worte eintragen
      T     LW [AR1,P#2.0]
      L     #DEST_DB                    // Quell-DB-Nummer eintragen
      T     LW [AR1,P#4.0]
      L     0                           // wenn Quell-DB-Nummer = 0 dann
// wird aus dem Merkerbereich 
      ==I                               // übertragen, sonst aus einem DB
      SPB   Merk
      L     P#DBX 0.0                   // Bereichspointer in Datenbaustein laden
      SPA   Offs
Merk: L     P#M 0.0                     // Bereichspointer in Merkerbereich laden
Offs: L     #DEST_Byte                  // Nummer des 1. zu kopierenden Bytes laden
      SLD   3                           // in Pointerformat wandeln
      +D                                // zum Bereichspointer addieren
      T     LD [AR1,P#6.0]              // Ergebnis in ANY-Ptr eintragen

 
  L     P##SRC_Any                  // Adr des Any-Ptr in AR1 legen
      LAR1  
      L     B#16#2                      // ist der Bereichstyp des übergebenen Any-Pointers
      L     B [AR1,P#1.0]               // = Byte oder = Word, erfolgt der Sprung
      ==I   
      O(    
      L     B#16#4
      ==I   
      )     
      SPB   Copy
      L     W#16#80FF                   // ansonsten Fehlerkennung laden
      T     #RET_VAL                    // an den Aufrufer übergeben
      SPA   Ende                        // Bausteinbearbeitung beenden
Copy: LAR2  P##T_SRC_Any                // Adr. des temp. Any-Ptr laden
      L     5                           // 5 Worte müssen kopiert werden
Back: T     #Count
      L     W [AR1,P#0.0]               // Umlegung des Any-Pointers als Inputvariable in
      T     LW [AR2,P#0.0]              // die Lokaldaten
      +AR1  P#2.0
      +AR2  P#2.0
      L     #Count
      LOOP  Back

 
CALL  "BLKMOV"
       SRCBLK :=#T_SRC_Any
       RET_VAL:=#SFC_Ret_Val
       DSTBLK :=#T_DEST_Any
 
  L     #SFC_Ret_Val
  T     #RET_VAL

Ende: LAR1  #T_AR1
        LAR2  #T_AR2
 
Naja, auf den ersten Blick hat das kein Ahnungsloser geschrieben, auf die Schnelle sehe ich da nichts.
Kannst Du nicht im Status in den Adressregister schauen was da passiert?

Und wie gesagt ist der Zielbereich vorhanden, in ausreichender Länge?

lG
Karl
 
Naja, auf den ersten Blick hat das kein Ahnungsloser geschrieben, auf die Schnelle sehe ich da nichts.
Stimmt der Code kommt aus der Hilfe zu AWL (Beispiel zum Datentyp Any).

Ich vermute, es liegt am
"FRG_HEIZ_KÜHL".VISU_AKT_SCHRITT

Gib' das doch mal so an: P#DB x.DBX y.0 Byte 16

Grüße
Gebs
 
Auf den ersten schnellen Blick würde ich #DB_Nr beim Schreiben prüfen. Steht da, warum auch immer, eine 0 drin, dann wird nicht in den DB geschrieben, sondern in den Merkerbereich.
 
Der Zeiger paßt so, denke ich. #DB_Nr zeigt dein Editor online nicht an. Entweder du legst dir den mal testweise vor genau vor dem Call FC (Daten schreiben) auf ein MW und siehst dir das am oder du schaust da nach, wo #DB_Nr beschrieben wird. Variante 1 wäre sicherer. Kann auch sein, daß nur beim Start der Funktion eine 0 anliegt und gleich danach eine korrekte DB-nummer, dann müßte man mal einen Trigger beim Start erzeugen und die #DB_Nr wegspeichern. Schwer zu sagen aus der Ferne.
 
Jo habs schon gemerkt, dann erscheint allerdings direkt der symbolische Name.

Und das ist auch das Problem. Habs bei mir schon öfter gehabt, dass der SFC 20 nicht funktioniert, sobald der Pointer durch den symbolischen Namen geändert wurde. (=> der Pointer wird auf DB x.DBX y.0 reduziert. Die Längenangabe fehlt dann)

Bau mal 'nen DB ohne Symbolik und probiers mal damit.

Grüße
Gebs
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und das ist auch das Problem. Habs bei mir schon öfter gehabt, dass der SFC 20 nicht funktioniert, sobald der Pointer durch den symbolischen Namen geändert wurde. (=> der Pointer wird auf DB x.DBX y.0 reduziert. Die Längenangabe fehlt dann)

Bau mal 'nen DB ohne Symbolik und probiers mal damit.

Grüße
Gebs

Wär mit neu, der Editor ist da nicht ganz korrekt, der zeigt das oft gar nicht mehr absolut an, besonders die Länge nicht. Wenn er die UDT (Struct) symbolisch anzeigt und die paßt, dann ist das m.E. nach i.O.
 
Ich hab' da glaub ich was verwechselt, das Problem mit der Symbolik hat der FC5 "AG_SEND".
siehe Bild

Grüße
Gebs
 

Anhänge

  • FC5_Fehler.bmp
    377,8 KB · Aufrufe: 10
Hallo Felse,

kopier doch mal folgenden Code vor deinen SFC20 Aufruf:

L P##DEST_Any // Adr des Any-Ptr in AR1 legen
LAR1
L w[AR1,P#0.0]
T MW 1000
L w[AR1,P#2.0]
T MW 1002
L w[AR1,P#4.0]
T MW 1004
L D[AR1,P#6.0]
T MD 1006

Bitte erst schaun ob MB1000..1010 noch frei sind !

Damit kopierst du den DEST_Any Pointer in den Merkerbereich MB1000..1010 und kannst dir dann mit einer VAT mal ansehen wie der dest-Pointer aussieht. Fehler 837F scheint ja wohl mit dem pointer ein Problem zu haben.

Bitte das Ergebnis posten.

mfG. klaly
 
Zurück
Oben