TIA SCL Indirekte Adressierung von global DB in einer Schleife

dakunz

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

Ich benutze eine 300er CPU mit TIA Portal v. 17.
Bin neu bei SCL und möchte gerne eine Funktion programmieren, welche mir alle Bits in einem globalen DB prüft ob eine "1" drin steht. Der DB hat insgesamt 14 Byte.
Ich wollte dies mit einer inneren und einer äußeren Schleife machen. Die innere für die Bitadresse und die äußere für die Byteadresse.
Hier ein Beispiel wie ich es ungefähr machen würde.

[CODE ANFANG]

FOR #i_outer := 0 TO 14 BY +1 DO

FOR #i_inner := 0 TO 7 BY +1 DO

IF %DB59.DBX0.0 <> 0 THEN
#StoerungAktiv := TRUE;
ELSE
#StoerungAktiv := FALSE;
END_IF;

END_FOR;

END_FOR;

[CODE ENDE]

Nun zu meiner Frage:
Wie kann ich in der Anweisung (IF %DB59.DBX0.0 <> 0 THEN) das DB indirekt mit meinen Zählvariablen abfragen also z.B. so:

IF %DB59.DBX#i_outer.#i_inner <> 0 THEN
...

Ist das überhaupt möglich? Wenn nicht was wäre eine andere Lösung?
Danke schonmal im Voraus für die Hilfe.

Viele Grüße
Daniel
 
Ich würd 3 Doppelworte und ein Wort jeweils auf ungleich 0 prüfen. Dann brauchst garkeine Schleife...

Also:
Code:
StoerungAktiv := DB59.DBD0<>0 OR DB59.DBD4<>0 OR DB59.DBD8<>0 OR DB59.DBW12<>0;

Oder willst Du pro jeweiligem Bit ne andere Aktion auslösen? Wenn ja, welche?
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Falls du die Schleife in der Schleife irgendwie zum Laufen bekommst hat das #StoerungAktiv immer den Zustand vom letzten Schleifendurchlauf. Was willst du denn abfragen? Es ist mindestens 1 Bit True?
 
siehe TIA Hilfe das Thema "Indirektes Adressieren von Datenbausteinen" (S7-300, S7-400)
oder das übergeordnete Thema "Indirektes Adressieren in SCL" (S7-300, S7-400)
da findest Du das Beispiel:
WORD_TO_BLOCK_DB("Adressindex").DX(#i,#y);

Was man in der Praxis braucht, steht allerdings nicht als Beispiel in der TIA-Hilfe: ;)
%DB1.DX(#i, #y); "MyDB".DX(#i, #y); WORD_TO_BLOCK_DB(#wDBnr).DX(#i, #y);

Deine Schleife macht so aber keinen Sinn, weil sie immer den Status des letzten Durchlaufs (DB59.DBX14.7) liefern würde. Außerdem ist "0 TO 14" falsch, wenn der DB nur 14 Byte lang ist. Was willst Du eigentlich erreichen?

Tipps:
Bool-Ausdrücke braucht man nicht auf 0 oder 1 oder FALSE oder TRUE zu vergleichen, sie liefern ja schon Bool und können direkt als Bool verwendet werden.
Wenn der ELSE-Zweig eines IF genau das logische Gegenteil vom THEN-Zweig tut (TRUE oder FALSE an dieselbe Variable zuweisen), dann kann man direkt den IF-Ausdruck an die Variable zuweisen:
Code:
//nicht so umständlich:
IF %DB59.DBX0.0 <> 0 THEN
    #StoerungAktiv := TRUE;
ELSE
    #StoerungAktiv := FALSE;
END_IF;

//sondern einfach so:
#StoerungAktiv := %DB59.DBX0.0;

Programmcode besser lesbar als Code formatieren:
Anhang anzeigen 67140

Harald
 
Zuletzt bearbeitet:
Ich würd 3 Doppelworte und ein Wort jeweils auf ungleich 0 prüfen. Dann brauchst garkeine Schleife...

Also:
Code:
StoerungAktiv := DB59.DBD0<>0 OR DB59.DBD4<>0 OR DB59.DBD8<>0 OR DB59.DBW12<>0;
Effizienter: erst alles verodern und nur das Ergebnis auf ungleich 0 vergleichen
Code:
#StoerungAktiv := (%DB59.DBD0 OR %DB59.DBD4 OR %DB59.DBD8 OR %DB59.DBW12) <> 0;
 
Zurück
Oben