Arrays in S7 schreiben

CrazyCat

Level-1
Beiträge
683
Reaktionspunkte
9
Zuviel Werbung?
-> Hier kostenlos registrieren
Ist es möglich für die S7 so etwas wie eine for - Schleife in C oder Basic zu schreiben?

Die Schleife würde in etwa o aussehen:

for (i = 1 to 100 step 1)
(Berechnungen)
.
.
.
Ergebnis = zwischen * exp (hilf)
next

Ich schaffe es nicht das Array über eine Variable zu schreiben.

Kann die S7 so etwas als AWL - Code.

Konkret ist mein Feld im DB151 und beginnt ab der Adresse DBD8. Die Variablen sind REAL - Variablen.
 
kannst du mit scl machen

geht aber auch leicht mit pointern in awl

Code:
      L     #Datenanfang
      T     #akt_dw

anf:  NOP   0                           //schleifenanfang

      L     #akt_dw
      SLD   3
      LAR1  
...
...
      T     DBD [AR1,P#0.0]

      L     #akt_dw
      L     4
      +D                                //nächstes dw
      T     #akt_dw
      L     #Datenende
      >D    
      SPB   ende                        //Schleifenende erreicht

      SPA   anf                         //zum Schleifenanfang
ende: nop 0
 
Danke!


Damit das funktioniert muss ich den DB zuerst öffnen, oder?

AUF DB151 //??????

Dann übertrage ich nur die Zahl der Anfangsadresse in akt_dw.

Also bei DB150.DBW20 muss in akt_dw 20 stehen, richtig?

Was bewirkt SLD3?

Wofür ist der Zusatz p#0.0?

Für akt_dw ist nur der Datentyp INT zulässig, oder?

Die Suche nach LOOP hat nichts ergeben.
 
Damit das funktioniert muss ich den DB zuerst öffnen, oder?

>>AUF DB151 //??????
richtig

>>Dann übertrage ich nur die Zahl der Anfangsadresse in akt_dw.
>>Also bei DB150.DBW20 muss in akt_dw 20 stehen, richtig?
richtig

>>Was bewirkt SLD3?
macht einen pointer aus akt_dw

>>Wofür ist der Zusatz p#0.0?
ist der versatz des pointers
wüdre hier z.b. p#4.0 stehen würdest du nicht auf dbd20 sondern auf dbd24 zugreifen

>>Für akt_dw ist nur der Datentyp INT zulässig, oder?
sollte doch wohl reichen,oder? oder hast du einen db der dw mit einer adresse > 32768 hat. :wink:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nochmals danke!

Werd' das sofort versuchen.

SLD bewirkt also einen Pointer, p#0.0 steht für den Versatz. Das ist für die Dokumentation sehr wichtig.

Der Kunde liest diese ständig und fragt bei solchen Sachen immer nach.
Würde schlecht aussehen, wenn ich nicht erklären könnte was der Befehl bewirkt.
 
Es geht ja auch ohne Loop, hier nur mal aus der AWL-Hilfe von Step7:

Format

LOOP <Sprungmarke>

Operand Beschreibung
<Sprungmarke> Symbolischer Name des Sprungziels.
Beschreibung

LOOP <Sprungmarke> (Dekrementiere AKKU1-L und springe, wenn AKKU1-L <> 0) vereinfacht die Programmierung von Schleifen. Der Schleifenzähler ist eine vorzeichenlose Ganzzahl (16 Bit) und befindet sich in AKKU1-L. Die Anweisung springt an das angegebene Sprungziel. Der Sprung wird ausgeführt, solange der Inhalt von AKKU1-L ungleich "0" ist. Der lineare Programmablauf wird am Sprungziel fortgesetzt. Dieses Sprungziel wird durch eine Sprungmarke angegeben. Es kann sowohl vorwärts als auch rückwärts gesprungen werden. Sprünge können nur innerhalb eines Bausteins ausgeführt werden, d. h. die Operation Programmschleife und das Sprungziel müssen innerhalb desselben Bausteins liegen. Das Sprungziel darf innerhalb dieses Bausteins nur einmal vorhanden sein. Die maximale Sprungweite liegt bei -32768 bzw. +32767 Wörtern des Programmcodes. Die tatsächliche maximale Anzahl der Anweisungen, die übersprungen werden können, hängt von der Kombination der Anweisungen innerhalb des Programms (Ein-, Zwei- oder Dreiwortanweisungen) ab.

Statuswort

BIE A1 A0 OV OS OR STA VKE /ER
schreibt: - - - - - - - - -
Beispiel zur Berechnung der Fakultät von 5 (5!)

Code:
AWL	Erläuterung
L	L#1	//Lade die Ganzzahl-Konstante (32 Bit) in den AKKU 1.
T	MD20	//Transferiere den Inhalt von AKKU 1 in MD20 (Initialisierung).
L	5	//Lade die Anzahl der Schleifenzyklen in AKKU1-L.
NEXT:	T	MW10	//Sprungmarke = Anfang der Schleife / Transferiere AKKU1-L in Schleifenzähler.
L	MD20	
*	D	//Multipliziere aktuellen Inhalt von MD20 mit aktuellem Inhalt von MB10.
T	MD20	//Transferiere Ergebnis der Multiplikation in MD20.
L	MW10	//Lade den Inhalt des Schleifenzählers in AKKU 1.
LOOP	NEXT	//Dekrementiere den Inhalt von AKKU 1 und springe zur Sprungmarke NEXT, wenn AKKU1-L > 0 ist.
L 	MW24	//Der Programmablauf wird nach dem Ende der Schleife hier fortgesetzt.
L	200
>I
 
Schleife in AWL

Hallo,

mit der S7 gibt es mehrere Möglichkeiten der Schleifenprogrammierung, durch die verschieden Softwareprodukte, die Siemens für die Steuerung anbietet.

Hier eine Lösungsmöglichkeit in AWL:

Code:
// Schleifen Voreinstellung
      L     L#0                         			// Schleifen anfangswert laden
      T     #DIT_Schleifenwert          		// Schleifenanfangswert laden

      L     L#1234                      		// Letzte Adresse zum bearbeiten
      T     #DIT_Schleifenende          		// Schleifenende speichern


// Schleifenausführung

RS50: L     DBD [#DIT_Schleifenwert]    	// DB-Bytewert zurücksetzen

// --- Aktion mit den geladenen Wert ---
// --- Ende ---

// Kontrolle auf Schleifenende

      SET                               		// VKE-1 laden
      L     #DIT_Schleifenwert          	// Schleifenanfangswert laden
      L     L#32                         		// Wert für Adressanpassung laden
      +D                                		// Adresse anpassen
      T     #DIT_Schleifenwert          	// Schleifenanfangswert speichern
      SRD   3                           		// Adresse für Schleifenende Kontrolle anpassen
      L     #DIT_Schleifenende          	// Schleifenende laden
      <D                                		// Wenn noch nicht alle Werte bearbeitet, dann
      SPB   RS50                        	// Sprung für erneuten Schleifendurchlauf

Wenn du noch Fragen hast, oder noch andere Varianten benötigst, melde dich bitte.[/code]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
kannst du mit scl machen

geht aber auch leicht mit pointern in awl

Code:
      L     #Datenanfang
      T     #akt_dw

anf:  NOP   0                           //schleifenanfang

      L     #akt_dw
      SLD   3
      LAR1  
...
...
      T     DBD [AR1,P#0.0]

      L     #akt_dw
      L     4
      +D                                //nächstes dw
      T     #akt_dw
      L     #Datenende
      >D    
      SPB   ende                        //Schleifenende erreicht

      SPA   anf                         //zum Schleifenanfang
ende: nop 0

Kann mir jemand das in fup darstellen?
 
Hi,wenn ich diese Schleife benutzen will bekomme ich immer Syntax Error, was mache ich falsch?
// Schleifen Voreinstellung
L L#0 // Schleifen anfangswert laden
T #DIT_Schleifenwert // Schleifenanfangswert laden
L L#1234 // Letzte Adresse zum bearbeiten
T #DIT_Schleifenende // Schleifenende speichern// Schleifenausführung
RS50: L DBD [#DIT_Schleifenwert] // DB-Bytewert zurücksetzen// --- Aktion mit den geladenen Wert ---// --- Ende ---// Kontrolle auf Schleifenende SET // VKE-1 laden L #DIT_Schleifenwert // Schleifenanfangswert laden L L#32 // Wert für Adressanpassung laden +D // Adresse anpassen T #DIT_Schleifenwert // Schleifenanfangswert speichern SRD 3 // Adresse für Schleifenende Kontrolle anpassen L #DIT_Schleifenende // Schleifenende laden <D // Wenn noch nicht alle Werte bearbeitet, dann
SPB RS50 // Sprung für erneuten Schleifendurchlauf

Der Fehler tritt bei "RS50: L DBD" auf
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Du mußt die Variable #DIT_Schleifenwert als Temp deklarieren und besser als DWord.

Code:
// Schleifen Voreinstellung
      L     L#0                         // Schleifen anfangswert laden
      T     #DIT_Schleifenwert          // Schleifenanfangswert laden
      L     L#1234                      // Letzte Adresse zum bearbeiten
      T     #DIT_Schleifenende          // Schleifenende speichern// Schleifenausführung
RS50: L     DBD [#DIT_Schleifenwert]    // DB-Bytewert zurücksetzen
// --- Aktion mit den geladenen Wert ---
// --- Ende ---
// Kontrolle auf Schleifenende
      SET                               // VKE-1 laden 
      L     #DIT_Schleifenwert          // Schleifenanfangswert laden 
      L     L#32                        // Wert für Adressanpassung laden 
      +D                                // Adresse anpassen 
      T     #DIT_Schleifenwert          // Schleifenanfangswert speichern 
      SRD   3                           // Adresse für Schleifenende Kontrolle anpassen
      L     #DIT_Schleifenende          // Schleifenende laden
      <D                                // Wenn noch nicht alle Werte bearbeitet, dann
      SPB   RS50                        // Sprung für erneuten Schleifendurchlauf

Code stellst du bitte mit den Code-Tags dar, wer soll das sonst lesen können?
 
Was sagt die Step7-Hilfe zu AWL beim Thema "Speicherindirekte Adressierung"? (praktischerweise mit F1 aufrufbar)

Pointer im Wordformat können nur für die speicherindirekte Adressierung von T, Z, DB, DI, FB, FC benutzt werden.
Für die speicherindirekte Adressierung von E, A, M, L, DIx, DBx, PEx, PAx müssen Pointer im Doppelwortformat verwendet werden, welche die genaue Adresse eines Bits, Bytes, Worts oder Doppelworts angeben: P#Byte.Bit . Bei Pointern auf Byte, Word oder Doppelword muß die Bitadresse 0 sein.

#DIT_Schleifenwert muß also ein DWORD oder DINT sein.

Wenn man versucht, das originale Programmbeispiel zu verstehen, dann sieht man höchstwahrscheinlich auch, daß das Programmbeispiel mit +D und >D arbeitet ...


Code:
RS50: L     DB[COLOR=#ff0000]D[/COLOR] [#DIT_Schleifenwert]

W=Word / Int
D = Doppel Word / Int
Der Datentyp von #DIT_Schleifenwert hat nichts mit dem DBD zu tun, auch DBW[#DIT_Schleifenwert] erfordert einen Pointer im Doppelwortformat ...

Harald
 
Auch wenn ich es schon geschrieben habe: In einem FB muss #DIT_Schleifenwert als Temp deklariert werden. Eine STAT führt ebenfalls zu einer Fehlermeldung!
 
Zurück
Oben