TIA symbolische (indirekte Adressierung)

dirknico

Level-2
Beiträge
218
Reaktionspunkte
14
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe einen FB, im Static-Bereich ein Array [1..16] of Bool.

Dies habe ich bisher indirekt adressiert um einzelne Bits zu setzen:
Code:
L P#84.0 /Adresse Array
T N8_P1 //Pointer

L 0
T DIW[N8_P1]

L Kurvenprogramm
L 1+
-I
L N8_P1
+D
T N8_P1

SET
S DIX [N8_P1]

Nun möchte ein Kunde aber keine indirekte Adressierung haben, sondern alles symbolisch.
Problem hierbei ist das ich das Array nicht symbolisch adressiert bekomme

Code:
L P##intern.Programm //besagtes Array
T N8_P1

wir von TIA nicht akzeptiert.

Jemand eine Idee wie ich es anders hinbekomme?
 
in einem Bool Array ein Bit symbolisch anzusprechen ginge z.b. so
S intern.Programm[0] // um das Bit an index 0 zu setzen (wenns den index gibt)
S intern.Programm[3] // um das Bit an index 3 zu setzen
S intern.Programm[N9_P1] // Um das Bit an Stelle von N9_P1 zu setzen. Wobei N9_P1 ein Integer ist. Die Absolutadresse ist also irrelevant sondern die relative Adresse im Array wird adressiert.

intern.Programm muss natürlich vom typ Array[1..16] of Bool sein (das sind 16 bit)

mfG René
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ok, das ist mir soweit klar.

Aber wie kann ich das gesamte Array beschreiben?
Code:
L 0 
T DIW[N8_P1]

Also hier das komplette INT wie z.B:
Code:
L P##intern.Programm //besagtes Array 
T N8_P1

was ja nicht funktioniert.......
 
Zuletzt bearbeitet:
Wenn du es komplett mit 0 überschreiben willst. wäre z.B. FILL_BLK angesagt.
Willst du ein komplettes array auf einen INT ummapen (warum auch immer) dann z.B. AT (in einem nicht optimierten Baustein)

mfG René
 
Möglichkeiten für symbolische Adressierung von Bits in Words:
Der Klassiker:
- die Bits ausmaskieren mit Wordverknüpfungs-AND, z.B.: WordVar AND W#16#0100
- das Word auf eine temporäre Bit-Struktur kopieren und da die Bits ansprechen
- AT-Sicht in SCL, oder AWL falls die CPU das unterstützt
- Slice-Zugriff, falls die CPU das unterstützt: Variable.x1

Alle direkt adressierten Bit-Zugriffe ala DBX.. oder DIX.. in nicht als Bool deklarierten Speicher sind heutzutage abzulehnen, wegen der hohen Gefahr, dabei unentdeckte und vom Compiler nicht verhinderbare Fehler zu machen, besonders bei Programmänderungen mit Verschiebung von Variablenadressen.

Nachtrag:
- man kann das Bit ins Statusbit A1 schieben oder rotieren und danach mit "U >0" abfragen (ins VKE holen)

Vorsicht! Bei indirekter Adressierung in den IDB muß der Multiinstanz-Offset aus AR2 korrekt addiert werden (benutze Forumssuche).
Besser: kopiere Dein Word in eine Bit-Struktur im TEMP (zweiter Vorschlag oben).

Nur Variablen in Speicherbereichen mit Standard-Zugriff haben Adressen, nur solche Variablen können indirekt adressiert werden. Sobald zu dem Bezug auf die Anfangsadresse einer Variable auch noch selbstgestrikte Pointer-Arithmetik mit Annahmen über eine bestimmte Speicherstruktur dazukommt, ist der Zugriff nicht mehr symbolisch.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
OK, zu schnell gepostet. Du brauchst es genau andersrum. Du hast bereits ein Bool-Array und willst es als gesamtes Word ansprechen. (Warum?)

Was für eine SPS willst Du programmieren?
Per Variable indizierte Adressierung von Bits in dem Bool-Array in AWL (#intern.Programm[N9_P1]) geht nur bei S7-1500. Bei S7-300/400 geht es nicht. Es ginge aber in SCL.

Bei S7-300/400 kann man außerdem in AWL nur die Anfangsadresse des äußersten Strukt ermitteln (P##intern), nicht aber die Adresse von Struktur-Membern (P##intern.Programm geht nicht). Man könnte nun noch den Offset des Struktur-Members 'Programm' zum Struktur-Anfang 'intern' fest dazuaddieren (z.B. [AR1, P#10.0]) (und den erwähnten Multiinstanz-Offset), was aber auch nicht viel besser als die direkten DIX/DIW-Zugriffe ist. Sowas sollte man nur einem Compiler überlassen. Einigermaßen sauber geht es tatsächlich nur in SCL.

Harald
 
Ich habe eine 1500 CPU (1517-3 PN/DP)
Ich habe ein INT - z.B. Anzahl Motoren, diese möchte ich im Programm mehrfach verwenden und hier nicht jedesmal einen Vergleicher haben um zu wissen ob Motor vorhanden oder nicht.
Also habe ich mir ein Array geschaffen mit der max. möglichen Anzahl von Motoren, und die indirekt entweder ganz oder teilweise beschrieben.
Aber indirekt darf jetzt nicht mehr - nur noch symbolisch.......
 
Ich habe eine 1500 CPU (1517-3 PN/DP)
Ich habe ein INT - z.B. Anzahl Motoren, diese möchte ich im Programm mehrfach verwenden und hier nicht jedesmal einen Vergleicher haben um zu wissen ob Motor vorhanden oder nicht.
Das klingt wie keine Lust, immer die lästigen Vergleiche einzutippen?

Warum willst Du in einem INT, in dem eine Anzahl steht, die einzelnen Bits ansprechen und dann auch noch indirekt?
Beispiel: Wenn Du wissen willst, ob die Zahl darin 8 oder größer ist, dann vergleicht man den INT-Wert auf >= 8 (>=I) - das geht prima symbolisch. Wenn Du stattdessen "vereinfacht" das Bit .3 prüfst, dann ist die Prüfung nicht korrekt, z.B. 17 ist >= 8, das Bit .3 ist aber 0.

In einer S7-1500 ist ein Vergleich eines symbolisch adressierten INT auf >= x hochwahrscheinlich vieeel performanter als eine indirekt adressierte Prüfung eines Bits. Wieviel oder wiewenig Schreibarbeit man als Programmierer hat sagt nichts über die Performance des erzeugten Maschinencodes. Und den Quellcode schreibt man nur einmal, der erzeugte mehr oder weniger performante Maschinencode wird aber Millionenfach ausgeführt.

Wenn es denn unbedingt mit einer Bool-Verknüpfung statt einem Vergleich sein soll: Am Anfang des Bausteins könntest Du den INT mittels 16 Vergleichen auf ein Bool-Array auspacken. Dies sollte insgesamt performanter sein als immer wieder indirekte Bit-Abfragen.
Code:
L #intern.AnzahlMotoren
L 1
>=I
= #temp.MotorVorhanden[1]

L #intern.AnzahlMotoren
L 2
>=I
= #temp.MotorVorhanden[2]
...

L #intern.AnzahlMotoren
L 16
>=I
= #temp.MotorVorhanden[16]
... 

U #starte_Motor
U #temp.MotorVorhanden[2]
= #Motor2

Wenn der Kunde auf symbolischer Adressierung besteht, dann besteht er vielleicht auch darauf, daß die DB "optimierten" Zugriff haben sollen? Da gehen Adress-Rechnungen gar nicht. Da muß man konsequent symbolisch indizierbare Strukturen einsetzen statt in Speicheradressen 'rumzupeeken/-poken. Und wenn man alle Bits eines Bool-Arrays löschen will, dann muß man halt jedes Bit einzeln symbolisch ansprechen (z.B. in einer Schleife), oder dem Compiler erklären, daß er das Array auf ein Word legen möge, damit man den vom Array belegten Speicher als Word ansprechen kann. Dies ist sauber und unabhängig von Speicheradressen.

Man muß nicht alle möglichen Schweinereien aus der S5- und S7-300-Programmierung in die neue S7-1500-Welt mitnehmen. Man sollte die Umstellung nutzen, endlich symbolische Algorithmen anzuwenden. Rechenpower ist genug vorhanden.

Harald
 
Zurück
Oben