-> Hier kostenlos registrieren
Hallo!
Ich bin neu auf dem Forum hier und generell auch in der SPS Programmierung.
Da ich mit KOP, FUP und SCL einigermaßen klar komme, wollte ich mich hier einmal an AWL versuchen.
Das ganze läuft in der Simulierung auf einer 300er CPU und ich programmiere im Simatic Manager.
Das Programm habe ich zuvor in gleicher Weiße in SCL funktionierend geschrieben.
Jedoch stoppt mir dieses Programm die CPU nach ein par Sekunden.
Wenn ich nun wie unten angegeben diese 3 Zeilen aus kommentiere, läuft das Programm zumindest durchgehend ohne Abbruch.
Außerdem bekomme ich seltsame Werte in meine REAL Arrays in den Datenbausteinen, wenn ich verkürzt versuche diese zu schreiben.
Das Programm soll mir Werte von IN auf meinen globalen DB1 ins Array[0..10] schreiben und das jede Sekunde einmal mithilfe des Eingang M0.5=TAKT machen.
Außerdem sollen im Anschluss jede Sekunde die Werte von DB1 genommen und in meinen globalen DB2 ins Array[0..10] umgedreht (unten nach oben) geschrieben werden.
--> In DB2 alle auf einmal, deswegen LOOP.
--> DB1 Soll jedoch nur jeden Durchlauf einmal Daten schreiben
Im Internet und in der HilfeDoku finde ich nicht heraus warum mein Programm fehlerhaft ist und auf Papier Zeile nach Zeile durchgegangen klingt es auch korrekt.
Könnte mir hier bitte jemand mit etwas mehr Erfahrung in der AWL Programmierung helfen?
Bg
Noebsi
Ich bin neu auf dem Forum hier und generell auch in der SPS Programmierung.
Da ich mit KOP, FUP und SCL einigermaßen klar komme, wollte ich mich hier einmal an AWL versuchen.
Das ganze läuft in der Simulierung auf einer 300er CPU und ich programmiere im Simatic Manager.
Das Programm habe ich zuvor in gleicher Weiße in SCL funktionierend geschrieben.
Jedoch stoppt mir dieses Programm die CPU nach ein par Sekunden.
Wenn ich nun wie unten angegeben diese 3 Zeilen aus kommentiere, läuft das Programm zumindest durchgehend ohne Abbruch.
Außerdem bekomme ich seltsame Werte in meine REAL Arrays in den Datenbausteinen, wenn ich verkürzt versuche diese zu schreiben.
Das Programm soll mir Werte von IN auf meinen globalen DB1 ins Array[0..10] schreiben und das jede Sekunde einmal mithilfe des Eingang M0.5=TAKT machen.
Außerdem sollen im Anschluss jede Sekunde die Werte von DB1 genommen und in meinen globalen DB2 ins Array[0..10] umgedreht (unten nach oben) geschrieben werden.
--> In DB2 alle auf einmal, deswegen LOOP.
--> DB1 Soll jedoch nur jeden Durchlauf einmal Daten schreiben
Im Internet und in der HilfeDoku finde ich nicht heraus warum mein Programm fehlerhaft ist und auf Papier Zeile nach Zeile durchgegangen klingt es auch korrekt.
Könnte mir hier bitte jemand mit etwas mehr Erfahrung in der AWL Programmierung helfen?
Bg
Noebsi
Code:
U #TAKT
UN #sFlankenMerker
= #sPosFlanke //Taktprüfer
U #sPosFlanke
SPB THEN //Bei positiver Flanke wird gearbeitet
SPA ELSE //Sonst übergeht SPB Befehl undspringt hier absolut zu ELSE
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
THEN: AUF "DB_DATA" //Arbeite in DB1
L #tZaehler
SLD 3
LAR1 //Schiebe AKKU1(Zähler) ins Adressregister
L #IN
T DBB [AR1,P#0.0] //Schreibe AKKU1(IN) auf Byte AR1(Zähler) der offenen Datenbank(DB1)
L 40 //Lade den Wert 40 in AKKU1 (Weil 0-10 ArrayMember mit je 4 Byte)
//DBZw:
T #tDB2Counter //Schreibe den Wert von AKKU1 auf den DB2Counter (Quasi DB2Counter := 40 TO 0 BY -4)
L #tDB2Counter
L 3 //Lade 3 in AKKU1 --> alter AKKU1 wird zu AKKU2 --> AK1=3, AK2=DB2Counter
==D //TRUE wenn AKKU1 und AKKU2 gleich sind
SPB LETZ
SPA NORM //Wenn SPB nicht TRUE war dann springe absolut auf NORM
LETZ: L #tDB2Counter
+ -3
T #tDB2Counter //Da letzter Durchlauf, subtrahiere 3 von DB2Counter damit DB2Counter = 0 wird
NORM: AUF "DB_DATA" //Öffne sicherheitshalber nochmals DB1
L #tForZaehler
SLD 3
LAR1 //Schiebe AKKU1(Schleifenzähler) ins Adressregister
L DBB [AR1,P#0.0] //Lade den Wert von Byte AR1(Schleifenzähler) der offenen Datenbank (DB1) auf AKKU1
T #tSave //Schreibe den Wert von AKKU1(DB1.DATA[Schleifenzähler]) auf einen Zwischenspeicher
AUF "DB_DATA_REVERSE" //Arbeite in DB2
L #tDB2Counter
SLD 3
LAR1 //Schiebe AKKU1(DB2Counter) ins Adressregister
L #tSave
T DBB [AR1,P#0.0] //Schreibe von AKKU1(Zwischenspeicher) auf Byte AR1(DB2Counter) der offenen Datenbank(DB2)
L #tForZaehler
+ 4 //Addiere zu AKKU1(Schleifenzähler) 4 dazu --> Schleifenzähler += 4 (4 Byte Sprünge im Array, da REAL Werte)
T #tForZaehler
L #tDB2Counter
L 4
<=D
SPB LAST //Vergleiche ob DB2Counter<=4 ist, da dann letzter Durchlauf ist/folgt
L #tDB2Counter
+ -3
T #tDB2Counter //Schreibe den Wert von AKKU1 in den DB2Counter (=DB2Counter-3, nur-3 da LOOP automatisch-1 von AKKU1 abzieht)
LAST: L #tDB2Counter
L 0
==D //Wenn Letzter Durchlauf Sprung, prüfe ob bereits gewesen(=0) oder noch kommt(=4)
SPB EINS
SPA NULL
EINS: L 1 //Schreibe 1 in DB2Counter wenn DB2Counter = 0, damit Loop nicht 0-1 rechnet
T #tDB2Counter
NULL: L #tDB2Counter
// LOOP DBZw //Ziehe 1 von AKKU1 ab und springe zu DBZw wenn AKKU1 <> 0
L 0
T #tForZaehler //Setze Schleifenzähler nach Schleife zurück
L #tZaehler
+ 4
T #tZaehler //Zähle einen Durchlauf auf
L 44 //Lade 44 in AKKU1 --> alter AKKU1 wird zu AKKU2 --> AK1=44, AK2=Zähler
// ==D //TRUE wenn AKKU1 und AKKU2 gleich sind --> Datenbaustein voll
SPB FULL
SPA ELSE //Wenn DB1 nicht voll dann gehe normal weiter
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
FULL: L 0
T #tZaehler //Setze Zähler zurück, wenn Datenbaustein voll
ELSE: U #TAKT
SPB EIN
R #sFlankenMerker //Resete den Flankenmerker
SPA ENDE //Wenn TAKT FALSE wird SPB übergangen und absolut auf AUS gesprungen
EIN: S #sFlankenMerker //Setze den Flankenmerker
SPA ENDE
ENDE: L 0
Zuletzt bearbeitet von einem Moderator: