TIA AWL Unterschiede S7-1500 zu S7-300

Machtnix

Level-2
Beiträge
77
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich muss ein Programm für eine S7-1500 schreiben, das sehr ähnliche Funktionen hat wie fertige Programme von mir für die 300er Serie.

Nun habe ich einen 300er AWL-Quelltext im TIA-Portal übersetzen lassen und es rappelt nur so an Fehlermeldungen. ZB meldet er SPB als Syntaxfehler. Die TIA Hilfe gibt da nichts her.

Es scheint also große Unterschiede zwische AWL-300 und AWL-1500 zu geben. Kennt jemand Dokumente, in denen die Unterschiede beschrieben sind?
 
ZB meldet er SPB als Syntaxfehler.
Kann es sein dass du noch die Standard-Einstellung "Englische Mnemonik" im TIA hast?
Dabei werden dann die englischen Abkürzungen in AWL verwendet.
"A" (AND) statt "U" (UND) und "JC" statt "SPB"...

Zu finden in den Einstellungen. Bis auf einige Details ist aber der meiste 300/400-AWL-Code direkt auf der 1500 lauffähig.
 
Ja, es war wohl so. Gesucht, gefunden und geändert. Nun sind es deutlich weniger Fehler. Meistens in Verbindung mit den optimierten DBs.

Leider in den Einstellungen nichts gefunden, dass nichtoptimierte Standard sein sollen.
 
Das Migrieren geht leider nicht, weil mein Step7-Manager in einer virtuellen Maschine ist und das TIA wegen hohem Speicherbedarf auf dem Host.

Aber ich habe herausgefunden, das eine Zeile

{ S7_Optimized_Access := FALSE }

im Quelltext hinter dem Titel eines Bausteins ihn als nichtoptimiert generiert. Das erspart, sie nach jedem Übersetzen neu umstellen zu müssen.

Jetzt gibt es noch Fehler in Bausteinen mit ANYPointer:

"Die Anweisung greift auf das DB bzw das DI-Register zu. Sie haben jedoch keinen Datenbaustein in diesem Register geöffnet."
 
Jetzt gibt es noch Fehler in Bausteinen mit ANYPointer:
"Die Anweisung greift auf das DB bzw das DI-Register zu. Sie haben jedoch keinen Datenbaustein in diesem Register geöffnet."
Da musst du schon ein wenig Code posten damit wir das genau sagen können.
Klingt als ob es um Zugriffe auf einen Datenbaustein via Adressregister geht.
TIA wird wahrscheinlich meckern dass es nirgendswo einen AUF-Befehl findet.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ein Beispiel:


Code:
FUNCTION "FCScanBits" : VOID
TITLE = Bitfeld scannen nach gesetzten Bits
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1


VAR_INPUT
 Bitfeld : ANY ; //Adresse
 von : INT ; // erstes Bit
 bis : INT ; // letztes Bit
 END_VAR
 
VAR_OUTPUT
 BitNum: INT ; //Erstes gesetztes Bit 0=Keins 
END_VAR



VAR_TEMP
 BitfP: DWORD; //Anfang Bitfeld
 Point: DWORD; //Arbeitszeiger
 Limit: DWORD; //Ende Suchbereich
 DBQ: INT; // Quell-DB
 
END_VAR

BEGIN

NETWORK
TITLE =


L P##Bitfeld; LAR1;

L W [AR1,P#4.0]; T #DBQ ;L 0; ==I;SPB NoDB;

AUF DB[#DBQ];

NoDB: L D [AR1,P#6.0]; T #BitfP; //Anfang Bitfeld

T #BitfP; L #bis; +D; T #Limit; //Ende

L #BitfP; L #von; +D; T #Point; //Anfang Suche




 
LOOP: NOP 0; 

L #Point; L #Limit; >=D; SPB NIX;

L #Point; LAR1;
L #Point; L 1; +D; T Point;

U DBX[AR1,P#0.0]; SPB FUND;
SPA LOOP;



FUND:
L #Point;L #BitfP;-D; T Bitnum;
BEA;

NIX:
L 0; T #Bitnum;
BE;

END_FUNCTION

AUF DB[#DBQ]; ist also drin.
 
Musst mal schauen an welcher Zeile der Fehler auftritt. Ich vermute aber in folgender...
Code:
      L     P##Bitfeld
      LAR1

      L     W [AR1,P#4.0]
      T     #DBQ
      L     0
      ==I
      SPB   NoDB

      AUF   DB[#DBQ];

NoDB: L     D [AR1,P#6.0]
      T     #BitfP        //Anfang Bitfeld
      T     #BitfP
      L     #bis
      +D
      T     #Limit        //Ende

      L     #BitfP
      L     #von
      +D
      T     #Point        //Anfang Suche

LOOP: NOP 0; 

      L     #Point
      L     #Limit
      >=D   
      SPB NIX

      L     #Point
      LAR1
      L     #Point
      L 1
      +D
      T     Point

[B][COLOR=#ff0000]      U     DBX[AR1,P#0.0][/COLOR][/B]
      SPB   FUND
      SPA   LOOP

FUND: L     #PointL
      L     #BitfP
      -D
      T Bitnum
      BEA

NIX:  L    0
      T #Bitnum
Wenn ich das richtig sehe...
An der Marke "NoDB" überspringst du gegebenenfalls das Laden eines DB. Der rot markierte Zugriff auf DBX wird aber trotzdem ausgeführt sofern Point<Limit.
 
Code:
L P##Bitfeld; LAR1;

L W [AR1,P#4.0]; T #DBQ ;[COLOR="#FF0000"]L 0; ==I;SPB NoDB;[/COLOR]

[COLOR="#FF0000"]AUF DB[#DBQ];[/COLOR]

[COLOR="#FF0000"]NoDB:[/COLOR] L D [AR1,P#6.0]; T #BitfP; //Anfang Bitfeld

[...]
 
LOOP: NOP 0; 

L #Point; L #Limit; >=D; SPB NIX;

L #Point; LAR1;
L #Point; L 1; +D; T Point;

U [COLOR="#FF0000"]DBX[/COLOR][AR1,P#0.0]; SPB FUND;
SPA LOOP;
Es wäre hilfreich, wenn Du noch angegeben hättest, welche Anweisung das TIA anmeckert.

Meine 50 cent zu dem Werk:
- vielleicht beschwert sich TIA, weil der DB nur bedingt geöffnet wird. Wenn die DB-Nummer im ANY "Bitfeld" 0 ist dann wird das "AUF DB[#DBQ]" übersprungen. Das Überspringen ist aber gar nicht nötig - "AUF DB0" ist kein Problem.
- in der Schleife wird mit "U DBX[AR1,P#0.0]" unbedingt aus einem DB gelesen, auch wenn vorher gar kein DB geöffnet wurde.
- das "AUF DB[#DBQ]" befindet sich an der falschen Stelle (VOR dem "L D [AR1,P#6.0]"), es gehört aber so nahe wie möglich vor die Schleife NACH den letzten Zugriff via [AR1;...]

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zwischenfrage: Wieso nicht einfach die Zeit nicht ins zum laufen bringen des Bausteine stecken sondern ihn einfach neu in SCL programmieren? Denke das wird sich auch für die Zukunft lohnen.

Gesendet von meinem SM-G930F mit Tapatalk
 
Es wäre hilfreich, wenn Du noch angegeben hättest, welche Anweisung das TIA anmeckert.

Das war leider nicht so leicht zu ermitteln. Das 'Gehe zu' hat leider keine Wirkung gezeigt. Zeilennummer war auch nicht angegeben. Mir war es aber auch so klar, da es die einzige Zeile ist, in der auf einen DB zugegriffen wird.

Meine 50 cent zu dem Werk:
- vielleicht beschwert sich TIA, weil der DB nur bedingt geöffnet wird. Wenn die DB-Nummer im ANY "Bitfeld" 0 ist dann wird das "AUF DB[#DBQ]" übersprungen.

Ja, das war es wohl. Ich hab das Überspringen gelöscht, und nun wird es ohne Fehler übersetzt. Der TIA-Übersetzer ist wohl pingeliger als der vom S7-Manager, dort gab es nur eine Warnung.


Das Überspringen ist aber gar nicht nötig - "AUF DB0" ist kein Problem.

Wo steht das, dass es kein Problem ist ? Als ich die ersten Anypointer-Funktionen geschrieben hab, dachte ich, es könnte zu einem Stop führen, da es keinen DB 0 gibt.
Nötig ist das Überspringen aber sowieso nicht, da ich sie nur in DB-Bereichen einsetze.


- das "AUF DB[#DBQ]" befindet sich an der falschen Stelle (VOR dem "L D [AR1,P#6.0]"), es gehört aber so nahe wie möglich vor die Schleife NACH den letzten Zugriff via [AR1;...]

Harald


Warum? Ein Zugriff über AR1 ist doch kein DB-Zugriff.
 
Zwischenfrage: Wieso nicht einfach die Zeit nicht ins zum laufen bringen des Bausteine stecken sondern ihn einfach neu in SCL programmieren? Denke das wird sich auch für die Zukunft lohnen.

Gesendet von meinem SM-G930F mit Tapatalk

Ich werde mich schon in Zukunft mehr mit SCL beschäftigen, auch wegen der 1200er. Es wäre aber ein Zeitproblem, jetzt alles neu zu schreiben in einer Sprache, die ich noch nicht so beherrsche.

Meine AWL-Schätze möchte ich schon noch weiter nutzen. Ich wollte ja nur wissen, was in TIA anders ist, und so sehr viel scheint das ja doch nicht zu sein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wo steht das, dass es kein Problem ist ? Als ich die ersten Anypointer-Funktionen geschrieben hab, dachte ich, es könnte zu einem Stop führen, da es keinen DB 0 gibt.
Nötig ist das Überspringen aber sowieso nicht, da ich sie nur in DB-Bereichen einsetze.
Der Befehl "AUF" tut nichts weiter als das DB-Register zu laden, es erfolgt kein Zugriff. Man schreibt also nur Null in das DB-Register.
Zum Stopp, den du beobachtet hast, kommt es erst wenn du einen Zugriff mit dem DB-Register versuchst, also beim "U DBX"

Ganz verstehe ich den Code auch nicht.
Wenn du das AUF überspringst liest dir dein "U DBX" normalerweise aus dem DB der vor dem FC-Aufruf zuletzt geöffnet war.
Bei einem FB wäre das Verhalten dann noch mal anders, bin mir jetzt aber nicht sicher wie dort das DB-Register nach dem Aufruf steht.

Warum? Ein Zugriff über AR1 ist doch kein DB-Zugriff.
Da hängt ganz davon ab was in dem Pointer bzw. dann im AR1 als Bereichskennung drinsteht.
Würde da ein W#16#84 drinstehen würde das AUF den L D[AR1]-Zugriff tatsächlich beeinflussen.
In deinem Fall hast du aber Glück da beim FC der übergebene ANY in den Vorgänger-Lokaldaten liegt und P##Bitfeld damit die Kennung W#16#87(V) enthalten müsste.
Dabei wird dann das DB-Register ignoriert. Wenn du nen FB hättest wäre die Kennung W#16#85(DI) enthalten und der L D[AR1]-Zugriff wäre vom DB2-Register beeinflusst.

Ich meine aber auch das ein AUF immer so nahe wie möglich an den Zugriff soll.

Theoretisch kannst du dir das "U DBX[AR1]" sparen und es gegen ein " U [AR1]" tauschen. Damit erfolgt der Zugriff in Abhängigkeit von der Bereichskennung im Pointer.
Wenn dein Bitfeld in einem DB-liegt, dann müsste dein #BitfP auch die Kennung W#16#84(DB) enthalten und der Zugriff in Kombination mit dem DB-Register richtig erfolgen.
Wenn das Bitfeld nicht in einem DB sondern z.B. im Temp des Vorgängers liegt, dann müsste über W#16#87(V) auch dorthin zugegriffen werden.
 
Zuletzt bearbeitet:
Der Befehl "AUF" tut nichts weiter als das DB-Register zu laden, es erfolgt kein Zugriff. Man schreibt also nur Null in das DB-Register.
Zum Stopp, den du beobachtet hast, kommt es erst wenn du einen Zugriff mit dem DB-Register versuchst, also beim "U DBX"

Ganz verstehe ich den Code auch nicht.

Das Überspringen war ursprünglich in einer Funktion, mit der der auch andere Bereiche (Merker,Ein- und Ausgänge, Lokaldaten...) abgefragt werden konnten. Da ich es als Vorlage für weitere Funktionen genommen habe, hat sich das sozusagen vererbt, obwohl es da nicht mehr sinnvoll ist.


Machtnix schrieb:
Warum? Ein Zugriff über AR1 ist doch kein DB-Zugriff. .
Da hängt ganz davon ab was in dem Pointer bzw. dann im AR1 als Bereichskennung drinsteht.
Würde da ein W#16#84 drinstehen würde das AUF den L D[AR1]-Zugriff tatsächlich beeinflussen.

Ich glaube du verwechselst da POINTER allgemein mit ANY. Der ANY-Pointer (#Bitfeld) zeigt auf einen Datenblock mit Informationen über das ANY-Objekt. In diesem Datenblock steht die Bereichskennung, aber nicht im POINTER . In den Anfangszeilen lese ich die benötigten Informationen (DBNummer, Bitadresse) aus dem Block in die Tempvariablen #DBQ und #Point. Mit den Anweisungen L #Point; LAR1; bekommt AR1 einen neuen Inhalt und hat garkeine Verbindung mehr zum ANY-Objekt.


Theoretisch kannst du dir das "U DBX[AR1]" sparen und es gegen ein " U [AR1]" tauschen. Damit erfolgt der Zugriff in Abhängigkeit von der Bereichskennung im Pointer.

Das wird nicht gehen, denn die Bereichskennung steht nicht im Pointerregister AR1, sondern im Datenblock, auf den er vorher gezeigt hat, aber jetzt nicht mehr. Nun ist in AR1 eine Bitadresse. Wenn in AR1 zB 3 steht, wird mit U DBX[AR1,P#0.0] der DBX 0.3 im zuletzt geöffneten DB abgefragt. Mit U M[AR1,P#0.0] wäre es M 0.3 , mit U E[AR1,P#0.0] wäre es E 0.3 usw. Und das alles ganz unabhängig davon, welche Bereichskennung im ANY-Block steht.
 
Ganz verstehe ich den Code auch nicht.
Wenn du das AUF überspringst liest dir dein "U DBX"
Das "U DBX" ist schlicht ein Programmierfehler (Bug), der nur noch nicht aufgefallen ist, weil der Code anscheinend nicht gründlich genug getestet wurde und an den Baustein bisher nur DB-Bereiche übergeben wurden.

Theoretisch kannst du dir das "U DBX[AR1]" sparen und es gegen ein " U [AR1]" tauschen. Damit erfolgt der Zugriff in Abhängigkeit von der Bereichskennung im Pointer.
Richtig, so wäre es korrekt.

Das wird nicht gehen, denn die Bereichskennung steht nicht im Pointerregister AR1
Doch, das funktioniert genau deshalb, weil in AR1 eine Bereichskennung aus dem ANY steht und in der Operation kein Bereich angegeben wird. Dann wird der Speicherbereich aus dem AR1 verwendet. Das "U [AR1..]" (ohne DBX) nennt sich "registerindirekte bereichsübergreifende Adressierung"

Mit U M[AR1,P#0.0] wäre es M 0.3 , mit U E[AR1,P#0.0] wäre es E 0.3 usw. Und das alles ganz unabhängig davon, welche Bereichskennung im ANY-Block steht.
Das nennt sich "registerindirekte bereichsinterne Adressierung". Es wird auf den Speicherbereich zugegriffen, der in der Operation extra angegeben ist, unabhängig davon, welche Bereichskennung im Adressregister steht.

Das Überspringen war ursprünglich in einer Funktion, mit der der auch andere Bereiche (Merker,Ein- und Ausgänge, Lokaldaten...) abgefragt werden konnten. Da ich es als Vorlage für weitere Funktionen genommen habe, hat sich das sozusagen vererbt,
Da wurde wohl leider nur unvollständig übernommen. In der Vorlage wurde bestimmt nicht mit "DBX [AR1...]" zugegriffen, sondern mit bereichsübergreifender Adressierung (ohne Bereichsangabe in der Operation) (oder mit einer Fallunterscheidung und separater bereichsinterner Operation für jeden Bereich). Sonst hätte der Zugriff auf die anderen Bereiche nicht funktioniert.

Ich glaube du verwechselst da POINTER allgemein mit ANY. Der ANY-Pointer (#Bitfeld) zeigt auf einen Datenblock mit Informationen über das ANY-Objekt. In diesem Datenblock steht die Bereichskennung, aber nicht im POINTER .
Ich glaube, da hast Du eine "Bildungslücke". POINTER ist quasi eine Untermenge von ANY, bei beiden enthält der 32-Bit-Adressteil (der in AR1 geladen wird) eine Speicherbereichskennung. Vielleicht schaust Du Dir mal in der Hilfe zu STEP7 den Aufbau von POINTER und von ANY genauer an.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
- das "AUF DB[#DBQ]" befindet sich an der falschen Stelle (VOR dem "L D [AR1,P#6.0]"), es gehört aber so nahe wie möglich vor die Schleife NACH den letzten Zugriff via [AR1;...]

Harald
Warum? Ein Zugriff über AR1 ist doch kein DB-Zugriff.
Wie RONIN schon schrieb, hast Du Glück, daß in FC Parameter über den TEMP-Stack übergeben werden und dadurch in AR1 NICHT die Bereichskennung "DB" steht und sich deshalb dieser Programmierfehler nicht auswirkt:
Code:
      L     P##Bitfeld
      LAR1                 //AR1 enthält die Adresse samt Bereichskennung des Übergabeparameters #Bitfeld

      L     W [AR1,P#4.0]  //es wird die DB-Nummer aus dem ANY gelesen (auf den der ANY zeigt)
      T     #DBQ
      L     0
      ==I
      SPB   NoDB

      [COLOR="#FF0000"]AUF   DB[#DBQ];[/COLOR]      //es wird der DB geöffnet, auf den der ANY zeigt

NoDB: [COLOR="#FF0000"]L     D [AR1,P#6.0]  //es soll nochmal aus dem ANY gelesen werden,[/COLOR]
                           [COLOR="#FF0000"]//der DB zeigt aber schon auf die Adresse aus dem ANY[/COLOR]
Würdest Du mit dem selben Vorgehen einen ANY auslesen, der in einem DB liegt, dann würde der letzte Zugriff nicht mehr aus dem ANY lesen, sondern aus dem DB, auf den der ANY zeigt.

Harald
 
Ja, ihr habt Recht, das hab ich inzwischen auch schon festgestellt. Die AR- Register können auch eine Bereichskennung enthalten (in den Bits 24-26). Und dann kann man auch ohne Bereichsangabe dereferenzieren.

Das U [AR1] reicht aber nicht, es muss schon U [AR1,P#0.0] sein.
 
Zurück
Oben