Step 7 Any-Pointer auf Lokaldaten in einem FC

Fireman_Frank

Level-2
Beiträge
154
Reaktionspunkte
28
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin,
im Lokaldatenbereich eines FC habe ich ab Adresse LW 10 einen String erzeugt, und will am Ende des FC die Textinformationen des String ohne die Längeninformationen (also ab LW 12) mittels BLKMOV umkopieren. Dazu wollte ich mir händisch eineen Any-Pointer auf eben dieses LW erstellen. Das funktioniert jedoch nicht. Seht selbst im Anhang.

Hat jemand ne Idee was ich da falsch gemacht habe?

Achso, der SFC20 meldet den Fehler w#16#8124:

Bereichsfehler beim Lesen eines Parameters.
Dieser Fehlercode zeigt an, daß sich der Parameter x in einem Bereich befindet, der für die Systemfunktion unzulässig ist. Die Beschreibung der jeweiligen Funktion gibt die Bereiche an, die für die Funktion unzulässig sind.

Frank

Anhang anzeigen Lokaldaten.pdf
 
Hallo Frank,
eigentlich sagt die Fehlermeldung schon alles aus : Der SFC kann auf den angegebenen Bereich nicht zugreifen. Es könnte sein, dass es mit "Vorgänger-Lokaldaten" funktioniert. Aber mal anders herum gefragt : was möchtest du am Ende erreichen ? Nach wohin gibst du die Daten am Ende aus (da hast du dann nämlich möglicherweise das nächste Problem) ?

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Larry, der Tip mit den 'Vorgänger-Lokaldaten' war gut, damit funktioniert es jetzt. Wobei ich nicht wirklich verstehe warum. Ich bleibe doch innerhalb eines FC, warum sind es dann die Vorgänger-Lokaldaten?

Die Ausgabeseite funktioniert. In diesem FC wird aus einem Real-Wert (in einem anderen FC passiert das gleiche auch mit Int-Werten) ein String erzeugt, dieser String ein wenig aufgehübscht (pos. Vorzeichen entfernt, Dezimalpunkt eingefügt, ggfs. Vornull eingefügt ...), dann ein Trennzeichen angefügt, und am Ende der entstehende Text an eine bestehende Zeichenkette (die in einem festen DB liegt) angehängt. So sollen zyklisch etwa 300 Meßwerte aus unserer Anlage als Textdatei mit Komma-separierten Werten per UDP zu einem Energieoptimierer gesandt werden :ROFLMAO:
 
Schau Dir mal die Dokumentation des SFC20 BLKMOV an, welche Speicherbereiche als Quell- und Zielbereich zulässig sind. Lokaldaten (TEMP) und Vorgänger-Lokaldaten sind da nicht dabei.
Verwende für das Verketten von Strings die Funktion CONCAT (Standard Library / IEC Function Blocks / FC2 CONCAT) - damit ist das Verketten symbolisch und ganz ohne ANY-Gebastel möglich, und die Strings dürfen auch in den Lokaldaten liegen.

Harald
 
Harald, ich hatte mir die Dokumentation des SFC20 schon angesehen. Diese ist allerdings etwas unglücklich. Zu Anfang des Hilfetextes stehen E/A/D/M beschrieben. Etwas tiefer bei der Parameterbeschreibung aber zusätzlich auch L.
Und mit den Vorgänger-Lokaldaten funzt es ja auch.
CONCAT scheidet aus weil ich ja genau aus einem String eine Zeichenkette machen will, also ohne die beiden führenden Bytes.

Edit: nach einigem Überlegen macht es mit den Vorgänger-Lokaldaten auch Sinn. Der von mir erstellte ANY-Pointer wird ja an den SFC20 geschrieben, was ja ein neuer (S)FC mit eigenen Lokaldaten ist.

Frank
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
ich hatte mir die Dokumentation des SFC20 schon angesehen. Diese ist allerdings etwas unglücklich. Zu Anfang des Hilfetextes stehen E/A/D/M beschrieben. Etwas tiefer bei der Parameterbeschreibung aber zusätzlich auch L.
OK, Du hast recht. Die übliche Schlampigkeit der Siemens Dokumentation ;)

CONCAT scheidet aus weil ich ja genau aus einem String eine Zeichenkette machen will, also ohne die beiden führenden Bytes.
Nur weil Du am Ende nach zig Basteleien die beiden Header-Bytes nicht brauchst, kannst Du doch trotzdem schön mit CONCAT zusammensetzen und die Header Bytes erst am Ende weglassen.

Eigentlich brauchst Du den BLKMOV (und CONCAT) aber überhaupt gar nicht. Das Basten des ANY ist ja schon aufwendiger als in einer Schleife die Quellbytes direkt in den Zielbereich zu kopieren. Die Schleife wäre sogar noch besser verstehbar. Du könntest das Zeichenkettenbasteln auch mit SCL programmieren - da geht das sehr schön symbolisch.

Übrigens: Der SCL-Compiler verwendet den SFC20 BLKMOV auch für das Kopieren aus den Lokaldaten (TEMP) und ersetzt dabei die Bereichskennung durch 16#87 (Vorgänger-Lokaldaten). Wenn Du unbedingt ANY basteln willst, dann solltest Du das so weit wie möglich symbolisch machen und nicht die absoluten L-Adressen in TEMP abzählen, z.B. so:
Code:
//Zusammenstellen des Quellzeigers
LAR1 P##QANY               //Pointer auf Adresse des ANY QANY
L    W#16#1002
T    LW [AR1, P#0.0]       //ANY: Typ Byte
L    #Anzahl_Zeichen_temp
T    LW [AR1, P#2.0]       //ANY: Anzahl
L    0
T    LW [AR1, P#4.0]       //ANY: DB

L    P##String_Temp        //Adresse des String(-Headers) mit Bereichskennung L (16#86..)
L    P#2.0                 //Länge String-Header = 2 Byte
+D                         //2 Byte weiter ist das erste Zeichen des String
//UD   DW#16#FFFFFF          //Bereichskennung L ausblenden - unnötig!
OD   DW#16#87000000        //Bereichskennung V (16#87000000)
T    LD [AR1, P#6.0]       //ANY: Bereichsadresse

//Zusammenstellen des Zielzeigers
LAR1 P##ZANY               //Pointer auf Adresse des ANY ZANY
L    W#16#1002
T    LW [AR1, P#0.0]       //ANY: Typ Byte
L    #Anzahl_Zeichen_temp
T    LW [AR1, P#2.0]       //ANY: Anzahl
L    #_DB_Nummer
T    LW [AR1, P#4.0]       //ANY: DB

L    #_Anzahl_Zeichen      //~Position/Adresse im Zielstring
SLD  3                     //zu Byteadresse konvertieren
L    P#DBX0.0              //Bereichskennung DB (16#84000000)
OD
T    LD [AR1, P#6.0]       //ANY: Bereichsadresse

CALL SFC20
 SRCBLK :=#QANY
 RET_VAL:=#HDW
 DSTBLK :=#ZANY

Harald
 
Wir nutzen bei uns bei Classic-Step 7 kein SCL. Aber danke für den Tipp mit der symbolischen Adressierung, das sieht wirklich ordentlicher aus.
 
Zurück
Oben