Step 7 Indirekte Adressierung auf IN- bzw.OUT-Schnittstelle eines FC´s

Katakis

Level-1
Beiträge
51
Reaktionspunkte
5
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute! Ich bin auf der Suche, die IN- und OUT-Schnittstelle eines FC´s indirekt einzulesen bzw. zu beschreiben. Im konkreten Fall will ich eine Menge Eingangsbits in den Lokaldatenbereich kopieren, um sie dort zu verarbeiten und entsprechend wieder als OUT-Variable zurückschreiben. "Zu Fuss" ist das halt mühsam und nicht schön, daher würde ich das Ganze gern als indirekte Schleife abarbeiten. Soweit ich weiss funktioniert ja nur der TEMP-Bereich mit L bzw. T LW [#adresse]. Was muss ich statt "LW" für IN- bzw. OUT-Bereich angeben?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hier ein ganz simples Beispiel. Ich möchte anhand der als IN-Variable übergebenen Zeit (z.B. 2 Sekunden) nacheinander die OUT-Variablen beschreiben. Wie gesagt, normale Wertvergleiche sind ja kein Thema, aber nicht schön. Daher will ich die OUT-Bits in einer Schleife indirekt beschreiben.
 

Anhänge

  • FC IN OUT.JPG
    FC IN OUT.JPG
    90,5 KB · Aufrufe: 139
Naja ... das ginge so (ist aber nicht so schön) :
Code:
L p##boTakt1
LAR1

U #Bedingung
= [AR1, p#0.0]  // adressiert boTakt1

L p#0.1
+AR1

U #Bedingung
= [AR1, p#0.0]  // adressiert boTakt2

// usw.
wie man daraus ggf. eine Schleife (oder was auch immer macht) weißt du sicherlich ...

Gruß
Larry
 
Ok, das war so naheliegend, dass ich es nicht ernsthaft in Betracht gezogen habe. Manchmal ist es eben doch besser, ein wenig einfacher zu denken. Vielen Dank für die Unterstützung!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi, du schreibst Die Bits sollen nacheinander beschrieben werden.

Was ich jetzt sehe ist das Du 32 Ausgangsbits hast und eine Fertigmeldung.
Da Du dir eine Menge Tiparbeit sparen möchtest, warum nimmst du für Den Ausgang nicht ein Doppelword und shiftest immer um eine Position nach Links? Ist vielleicht ein ganz anderer Denkansatz.

Gruß Peter
 
Ginge natürlich auch. Aber dann hast du bei der Aufrufschnittstelle nur ein Doppelwort, das du angeben kannst. In meinem Fall geht es um die Taktung von Leckagesitzen von Doppelsitzventilen über ASi-Bus. Da ist es mir schon recht, wenn ich die Bit-Adressen einzeln angeben kann. Klar, wenn ich den OUT-Bereich genauso wie den L-Bereich adressieren kann, ist das auch eine überlegenswerte Sache. Dann bleibt die Aufrufschnittstelle "leserlich" und ich dann trotzdem im FC doppelwortweise rumrangieren.
 
Achtung, der Code von Larry funktioniert nur in einem FB.
In einem FC liefert "L P##boTakt1" NICHT die Adresse des Ausgangsparameters boTakt1 sondern die Adresse der am Ausgang boTakt1 angeschlossenen Variable.

Die IN-/OUT-Parameter eines FC können imho nicht in einer Schleife indirekt adressiert werden.

Man könnte ein ARRAY_OF_BOOL oder ein DWORD übergeben und darin die Bits indirekt adressieren.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, indirekt auf IN/OUT bei FC ist gefährlich.

Achtung, der Code von Larry funktioniert nur in einem FB.
In einem FC liefert "L P##boTakt1" NICHT die Adresse des Ausgangsparameters boTakt1 sondern die Adresse der am Ausgang boTakt1 angeschlossenen Variable.
Und nicht einmal das direkt.

Kleines Bespiel...
attachment.php


Wenn man am FC-Ausgang einen Merker verwendet, dann kommt man im FC an die Adresse dran.
Wenn man am FC-Ausgang jedoch ein Datenbaustein-Bit verwendet, dann nicht mehr direkt.
Mann kann dann schon mittels Pointer auf die Adressen schreiben, man schreibt dann halt nur irgendwohin...

Ein weiteres Problem ist der Unterschied ob der FC in FUP oder AWL aufgerufen wurde.
Hier ein Beispiel für den Unterschied und was man jeweils bekommt wenn man versuch indirekt auf in Parameter zuzugreifen.
attachment.php
attachment.php

Allein dieser Unterschied macht es schon so gut wie unmöglich sinnvoll auf diese Weise zu arbeiten.



Die SPS legt beim Aufruf des FC die IN/OUT-Parameter in den Temp-Bereich und arbeitet dann intern mit Pointern auf die "Vorigen Lokaldaten".
IM FUP-Aufruf macht der AWL-Umsetzer das noch vorher (sichtbar), beim direkten AWL-Aufruf macht's die Maschine (unsichtbar)
Nach dem FC-Aufruf wird dann wieder vom TEMP auf die eigentlichen Adressen kopiert.

Ich wusste aber schon mal besser über dieses Verhalten bescheid. Vielleicht kann ja hier noch mal jemand genauer Licht ins Dunkel bringen wie das Handling bei den FCs funktioniert. Vor allem der Unterschied wenn man einen Merker und
einen DB am OUT hat....
Würd mich jetzt echt nochmal interessieren...

@Katakis
Für deinen Fall wird's wohl das einfachste sein wenn du...
a) einen FB draus machst
b) Wenn's ein FC sein muss würd ich's vermutlich so machen:
- Doppelwort an FC - IN/OUT als Speicher

- Doppelwort auf ein 32Bit-Array im Temp kopieren
- Bits entsprechend manipulieren
- Bits aus Temp auf FC-Out kopieren
- 32Bit Array aus Temp wieder auf Doppelwort in FC-IN/OUT sichern.
 

Anhänge

  • FC_Out_Ind.jpg
    FC_Out_Ind.jpg
    74,7 KB · Aufrufe: 175
  • FC_IN_IndirekterZugriff_AWLAufruf.jpg
    FC_IN_IndirekterZugriff_AWLAufruf.jpg
    135,8 KB · Aufrufe: 147
  • FC_IN_IndirekterZugriff_FupAufruf.jpg
    FC_IN_IndirekterZugriff_FupAufruf.jpg
    117,9 KB · Aufrufe: 131
Zuletzt bearbeitet:
Richtig, bei Datenbaustein-Bit als Aktualparameter liefert "L P##boTakt1" die Adresse der Kopie der Aktualvariable im L-Stack (Vorgänger-Lokaldaten).

Was ist bei der Parametrierung der Ein- und Ausgangsparameter einer Funktion zu beachten?
189227 schrieb:
2.Versorgung der elementaren Ein- und Ausgangsparameter

Bei der Versorgung von elementaren Formalparametern (z.B. die Datentypen BOOL, BYTE, WORD oder DWORD) der Schnittstelle einer Funktion sind zwei Fälle zu unterscheiden.
  1. Der elementare Formalparameter wird mit einem Merker, einem Ein- oder Ausgang aus dem Prozessabbild oder aus dem Lokaldatenstack (L-Stack) des aufrufenden Bausteines versorgt.
    In diesem Fall arbeitet der Code der Funktion mit einem bereichsübergreifenden Zeiger direkt(!) auf diesen elementaren Aktualparametern (z.B. P#E0.0, P#M0.0).
  2. Der elementare Formalparameter wird mit einer Konstanten oder einem Datenbausteinelement versorgt.
    In diesem Fall wird der Wert des Aktualparameters vor dem Aufruf der Funktion in den L-Stack des aufrufenden Bausteines kopiert. Der Code der Funktion arbeitet dann mit einem bereichsübergreifenden Zeiger auf diesen Lokaldatenbereich des aufrufenden Bausteines.

Oder siehe hier die Zitate aus der Step7 Hilfe zu AWL > Parameterübergabe


Im übrigen empfehle ich, im Interesse der Lesbarkeit des Codes durchaus die Mehr-Tipparbeit wegen sauberem symbolischen Zugriff auf jeden einzelnen Ausgang zu leisten. Man sieht ja an TIA, daß vollsymbolisches Programmieren die Priorität hat - da sind indirekte absolute Adressierungen häufig unmöglich oder nur noch extrem aufwendig zu realisieren.

Harald
 
Ja, eigentlich eh klar....

P#E0.0 ... geht
P#M0.0 ... geht

aber da im Pointer-Format keine DB-Nummern stehen, gehts natürlich nicht direkt.
 
Zurück
Oben