Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: DB Nr. an FC übergeben

  1. #1
    Registriert seit
    13.05.2008
    Beiträge
    316
    Danke
    43
    Erhielt 23 Danke für 15 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    *gelöscht*
    Geändert von Beren (04.07.2011 um 17:19 Uhr)
    Zitieren Zitieren DB Nr. an FC übergeben  

  2. #2
    Registriert seit
    16.05.2007
    Ort
    im Stahlwerk...
    Beiträge
    1.178
    Danke
    120
    Erhielt 429 Danke für 236 Beiträge

    Standard

    1. Möglichkeit:
    IN-Parameter vom Typ INT, z.B. #INDB
    dann von IN-Parameter auf Temp-Parameter umwandeln
    Code:
    L #INDB
    T #MEINDB
     
    AUF DB[#MEINDB]
    2. Möglichkeit:
    IN-Parameter vom TYP BLOCK_DB deklarieren

    Gruß Approx
    Nihil est in cpu, quod non fuerit in intellectu" - Nichts ist in der CPU, was nicht (zuvor) im Verstand war.

  3. Folgender Benutzer sagt Danke zu Approx für den nützlichen Beitrag:

    Beren (05.05.2010)

  4. #3
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.166
    Danke
    921
    Erhielt 3.286 Danke für 2.655 Beiträge

    Standard

    Es sollte nur die 2. Möglichkeit von Approx benutzt werden, diese erzeugt aussagekräftige Referenzdaten.
    Code:
    VAR_INPUT
      DBNr : BLOCK_DB ;
    END_VAR
    
    AUF #DBNr
    Bei der 1. Möglichkeit (AUF DB[#MEINDB]) muß für eine Programm-Analyse manuell jeder Bausteinaufruf angesehen
    werden! Diese Möglichkeit ist eigentlich nur nötig, wenn die DB-Nummer vor dem Aufruf indirekt ermittelt wird.

    Gruß
    Harald
    Zitieren Zitieren IN-Parameter vom TYP BLOCK_DB deklarieren  

  5. Folgender Benutzer sagt Danke zu PN/DP für den nützlichen Beitrag:

    Beren (05.05.2010)

  6. #4
    Registriert seit
    14.11.2008
    Beiträge
    66
    Danke
    3
    Erhielt 6 Danke für 6 Beiträge

    Standard

    Ich denke eher, es sollte nur die 1. Möglichkeit benutzt werden.

    Bei der 2. Möglichkeit kann man den FC nicht mehr aus einem übergeordneten FC heraus aufrufen und den DB weiterleiten, egal wie die DB-Nr. vorliegt. Geht es doch irgendwie? -> Bitte um Aufklärung

    Wie das mit den Referenzdaten ist, weiß ich nicht. Ist es irgendwie möglich, mehr als die Tatsache, dass DB X übergeben wurde, nachzuvollziehen? Werden AUF-Befehle nicht mit erfasst?

    Die Parameterübergabe geht am einfachsten so:
    AUF "db_whatever";
    L DBNO;
    T #tmp_int;
    CALL ... := tmp_int, ...

    Auch hier kenne ich keine bessere Möglichkeit, gibt es eine? Bei Direktübergabe würde der DB-Name nicht mehr im Code stehen.

  7. Folgender Benutzer sagt Danke zu Drutbluck für den nützlichen Beitrag:

    Beren (05.05.2010)

  8. #5
    Avatar von Beren
    Beren ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    13.05.2008
    Beiträge
    316
    Danke
    43
    Erhielt 23 Danke für 15 Beiträge

    Standard

    *gelöscht*
    Geändert von Beren (04.07.2011 um 17:19 Uhr)

  9. #6
    Avatar von Beren
    Beren ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    13.05.2008
    Beiträge
    316
    Danke
    43
    Erhielt 23 Danke für 15 Beiträge

    Standard

    *gelöscht*
    Geändert von Beren (04.07.2011 um 17:19 Uhr)

  10. #7
    Avatar von Beren
    Beren ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    13.05.2008
    Beiträge
    316
    Danke
    43
    Erhielt 23 Danke für 15 Beiträge

    Standard

    *gelöscht*
    Geändert von Beren (04.07.2011 um 17:19 Uhr)

  11. #8
    Registriert seit
    16.05.2007
    Ort
    im Stahlwerk...
    Beiträge
    1.178
    Danke
    120
    Erhielt 429 Danke für 236 Beiträge

    Standard

    Zitat Zitat von Beren Beitrag anzeigen
    Und wie übergebe ich einen Pointer?

    Ich habe per IN die DB Nr. an meinen FC übergeben.

    Im FC habe ich den DB mit AUF #DBNr geöffnet.

    Nun möchte ich per

    LAR1 P#XXX.X eine bestimmte Stelle im DB referenzieren, die von aussen übergeben werden soll. Wie mach ich das?
    Hier der passende Link zur FAQ

    Gruß Approx
    Nihil est in cpu, quod non fuerit in intellectu" - Nichts ist in der CPU, was nicht (zuvor) im Verstand war.

  12. #9
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.166
    Danke
    921
    Erhielt 3.286 Danke für 2.655 Beiträge

    Standard

    Zitat Zitat von Approx Beitrag anzeigen
    1. Möglichkeit:
    IN-Parameter vom Typ INT, z.B. #INDB
    dann von IN-Parameter auf Temp-Parameter umwandeln
    Code:
    L #INDB
    T #MEINDB
     
    AUF DB[#MEINDB]
    2. Möglichkeit:
    IN-Parameter vom TYP BLOCK_DB deklarieren
    Zitat Zitat von Drutbluck Beitrag anzeigen
    Ich denke eher, es sollte nur die 1. Möglichkeit benutzt werden.

    Bei der 2. Möglichkeit kann man den FC nicht mehr aus einem übergeordneten FC heraus aufrufen und den DB weiterleiten, egal wie die DB-Nr. vorliegt. Geht es doch irgendwie? -> Bitte um Aufklärung
    An einen aufgerufenen FB kann man einen IN.BLOCK_DB weitergeben (aus FB und FC), an einen FC geht es nicht.
    Wenn man also einen BLOCK_DB durchleiten will, muß man eben den aufgerufenen Baustein als FB schreiben.
    Braucht man die DBNr-Weitergabe aber tatsächlich praktisch? Ich habe es noch nicht gebraucht.

    An einen FB werden die Parameter über dessen Instanz-DB übergeben, an einen FC über den L-Stack (vorherige Lokaldaten).
    Da hat Siemens wohl das entsprechende MC7-Macro für FC "vergessen". Eigentlich spricht nichts dagegen.

    Übrigens witzig zu sehen, wie inkonsequent das S7-AWL ist:
    Code:
    VAR_INPUT
      DBNr : BLOCK_DB ;
      Offset : INT ;
    END_VAR
    
          L     #DBNr       // Anweisung nicht erlaubt für BLOCK_DB-Befehls-Operanden
          LAR1  P##DBNr     // Symbol DBNr nicht gefunden oder nicht erlaubt in Anweisung mit Adress-Operator P#
    
          L     P##DBNr     // das ist erlaubt
          LAR1              // ergibt aber einen sinnlosen Pointer ohne Bereichskennung
    
    
          L     #Offset     // das ist erlaubt - muß ja auch
          LAR1  P##Offset   // Symbol Offset nicht gefunden oder nicht erlaubt in Anweisung mit Adress-Operator P#
    
          L     P##Offset   // das ist erlaubt
          LAR1              // ergibt einen Pointer auf die vorherigen Lokaldaten

    Zitat Zitat von Drutbluck Beitrag anzeigen
    Wie das mit den Referenzdaten ist, weiß ich nicht. Ist es irgendwie möglich, mehr als die Tatsache, dass DB X
    übergeben wurde, nachzuvollziehen? Werden AUF-Befehle nicht mit erfasst?
    Da gibt es doch so clevere Programmierer, die machen jeglichen Datentransfer zwischen DB mit so einem Baustein:
    Code:
    VAR_INPUT
      Source_DB : INT ;     // müsste korrekterweise WORD sein, 
      Source_Offset : INT ; // aber INT läßt sich viel bequemer
      Dest_DB : INT ;       // mit dezimalen Aktualwerten versorgen
      Dest_Offset : INT ;   // (da muß der Programmierer nicht in Hex denken)
      Len : INT ;
    END_VAR
    
          L     #Source_DB
          T     MW   200    // sogar zu faul, ein TEMP-WORD anzulegen!
          AUF   DB [MW 200]
    
          L     #Dest_DB
          T     MW   200
          AUF   DI [MW 200]
    
    // indirekte BYTE-Kopierschleife (möglichst uneffizient geproggt)
    //    ...
    Die beiden AUF-Befehle tauchen in den Referenzdaten NICHT auf!!!
    Die Benutzung der DB als Aktualwerte beim CALL taucht erst recht nicht auf (sind ja als INT deklariert).

    Es hilft nur, auf Verdacht eine AWL-Quelle mit allen FB+FC+OB zu erzeugen und nach "AUF~~~D" zu suchen (~ ist Leerzeichen).
    Damit hat man zunächst die "bösen" Bausteine ertappt.
    Nun noch Viel Spaß beim ansehen ALLER Aufrufe dieser Bausteine und aufschreiben, welche DB dabei benutzt werden!

    Wenn schon sowas fieses, dann sollte es wenigstens so sein:
    Code:
    VAR_INPUT
      Source_DB : BLOCK_DB ;
      Source_Offset : INT ;
      Dest_DB : BLOCK_DB ;
      Dest_Offset : INT ;
      Len : INT ;
    END_VAR
    
          AUF   #Dest_DB
          TDB
          AUF   #Source_DB
    // ( DBNO=#Source_DB / DINO=#Dest_DB )
    
    // indirekte BYTE-Kopierschleife
    //    ...
    Nun steht die Benutzung der DB für jeden Baustein-Aufruf in den Referenzdaten, z.B. so:
    DB 1 | FC11 | R | AWL | NW 1 Anw 1 /CALL
    DB 2 | FC11 | R | AWL | NW 1 Anw 1 /CALL
    DB 3 | FC11 | R | AWL | NW 2 Anw 1 /CALL
    DB 3 | FC11 | R | AWL | NW 2 Anw 1 /CALL

    Die eigentlichen AUF-Befehle im Baustein stehen aber trotzdem nicht in den Referenzdaten.
    Man kann nun aber wenigstens ahnen, woher die Daten im DB kommen.


    Zitat Zitat von Drutbluck Beitrag anzeigen
    Die Parameterübergabe geht am einfachsten so:
    AUF "db_whatever";
    L DBNO;
    T #tmp_int;
    CALL ... := tmp_int, ...

    Auch hier kenne ich keine bessere Möglichkeit, gibt es eine? Bei Direktübergabe würde der DB-Name nicht mehr im Code stehen.
    Na, wenigstens schreibst Du die DB-Nummer als INT nicht direkt in den CALL ...

    Bei BLOCK_DB als Formalparameter steht ganz sicher der DB-Name im Code, ggf. sogar symbolisch. Das geht einfach so:
    Code:
          CALL  FC12
           DBNr :="db_whatever"     //z.B. DB123 eintippen
    Und steht in den Referenzdaten als: DB 123 (db_whatever) | FC11 | R | AWL | NW 1 Anw 1 /CALL

    Also, ich bin der Meinung, daß man wegen den Referenzdaten eine DB-Nummer immer als BLOCK_DB übergeben soll.
    Und nur ausnahmsweise - wenn es wirklich zwingende Gründe gibt - die DB-Nummer als INT/WORD übergeben.

    Gruß
    Harald
    Zitieren Zitieren Warum DB-Übergabe als BLOCK_DB?  

  13. Folgender Benutzer sagt Danke zu PN/DP für den nützlichen Beitrag:

    Drutbluck (06.05.2010)

  14. #10
    Registriert seit
    14.11.2008
    Beiträge
    66
    Danke
    3
    Erhielt 6 Danke für 6 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ich hatte das Problem, als ich einen gegebenen FC mit sehr vielen Parametern incl. BLOCK_DB aus einem FB aufrufen wollte, die DB-Nr. war als Variable vorgegeben.

    Meine erste "Lösung" war, den Aufruf für alle denkbaren DB-Werte zu kopieren.

    Ich denke, das Problem bei der Übergabe ist, dass für jeden Parameter ein Pointer im Code selbst steht: (in einer Art Pseudoassempler)
    ...Code...
    jmp to_call;
    DATA P#...
    DATA P#...
    to_call: CALL ...
    ...Code...

    Ein BLOCK_XX steht direkt drin, nicht als Pointer, dadurch ist er notwendigerweise konstant.

    POINTER sind nicht konstant, man kann wahrscheinlich auch Pointer weiterleiten, etc.
    Dadurch braucht man keine db_nr: INT; addr: DINT; als Parameter, ich bevorzuge POINTER oder gar VAR_IN_OUT xxx: udt_yyy;

    Bei POINTERN ist nur innerhalb der FC hässlicher Code, der Aufruf kann ok sein. Bei VAR_IN_OUT UDTs ist der Code überall lesbar. Aber bei INT/DINT-Kombis für Pointer ist der Aufruf *und* der Code im FC schwierig.


    Das AUF #variable nicht in den Referenzdaten ist, wundert mich nicht. Schließlich wurde die Variable irgendwann mal versorgt, hoffentlich mit einem DB, dann kann das in die Referenzdaten. Jetzt muss ich nur noch prüfen, ob AUF "konstanter_db" in die Referenzdaten kommt ...

Ähnliche Themen

  1. DB in SCL übergeben
    Von Felse im Forum Simatic
    Antworten: 20
    Letzter Beitrag: 11.09.2012, 19:50
  2. Any Übergeben an FB
    Von xvitali im Forum Simatic
    Antworten: 8
    Letzter Beitrag: 24.03.2011, 10:48
  3. MW in INT Variable übergeben
    Von Felse im Forum Simatic
    Antworten: 1
    Letzter Beitrag: 10.03.2009, 10:13
  4. Textdatei an SPS übergeben
    Von stau im Forum HMI
    Antworten: 11
    Letzter Beitrag: 29.07.2008, 14:42
  5. UDT an FB übergeben
    Von Ralle im Forum Simatic
    Antworten: 5
    Letzter Beitrag: 30.11.2005, 10:34

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •