S7-1200: Zugriffsmöglichkeiten auf Pheripherie?

joergflorian

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

Ich habe seit kurzem eine S7-1200. Nun wollte ich das lesen und schreiben der Daten auf die Pheripherie ähnlich wie bisher bei der 315 umsetzen. D.h. am Bausteineingang die E-/A-Adressen der Module des Geräts als INT angeben und dann entsprechend mit PEW, PAW, bzw. SFC14 /SFC15 die Daten lesen bzw. schreiben.

Das sah bisher etwa so aus:
Lesen
Code:
// 1 Wort lesen
L     #AdrStatusWord              //Check address >0, else skip
L     0
>I    
SPBN  Ne1a

L     #AdrStatusWord
SLD   3

LAR1  
L     PEW [AR1,P#0.0]
T     #Axis.ComData_IN.StatusWord


// 4 Worte konsistent lesen
L     #AdrParameterChannel        //Check address >0, else skip
L     0
>I    
SPBN  Ne2a

L     #AdrParameterChannel
T     #Adr_Temp

CALL  "DPRD_DAT"
 LADDR  :=#Adr_Temp
 RET_VAL:=#Temp_Ret_Val
 RECORD :=#ConfigData_IN
NOP   0

Schreiben
Code:
// 1 Wort schreiben
L     #AdrControlWord
SLD   3

LAR1  
L     #Adr_Temp
T     PAW [AR1,P#0.0]

// 4 Worte konsistent schreiben
L     #AdrParameterChannel
T     #Adr_Temp

CALL  "DPWR_DAT"
 LADDR  :=#Adr_Temp
 RECORD :=#ConfigData_OUT
 RET_VAL:=#Temp_Ret_Val
NOP   0


Nun habe ich ja bei der 1200 die Funktionen PEEK und POKE, um auf z.B. ein Word/DWord etc. zuzugreifen, wenn ich die E-/A-Adresse weiss.

Lesen
Code:
// 1 Wort lesen
IF NOT (#AdrStatusWord = 0) THEN
  #Axis.DrvToPlc.StatusWord := PEEK_WORD(area:=16#81, dbNumber:=0, byteOffset:=#AdrStatusWord);
END_IF;

Schreiben
Code:
// 1 Wort schreiben
IF #AdrControlWord <> 0 THEN 
 POKE(area:=16#82,
       dbNumber:=0,
       byteOffset:=#AdrControlWord,
       value:=#Axis.PlcToDrv.ControlWord);
END_IF;

Zum Lesen und Schreiben von Modulen >= 4 Worte verwende ich immer noch die DPRW_DAT und DPRD_DAT, aber die verlangen als LADDR nun eine HW_IO_Adresse, welche ja automatisch beim projektieren angelegt wird. Funktioniert natürlich auch.

Meine Frage nun:
Gibt es eine Möglichkeit entweder alles per HW_IO_Adressen oder alles per E-/A-Adressen zu lesen/schreiben?
Irgendwie gefällt mir das nicht für Module mit einem Wort die E-/A-Adresse zu verwenden und für >=4 Worte die HW_IO_Adresse.

Ich hoffe ich habe mich verständlich ausgedrückt.

Vielen Dank für eure Inputs
Florian
 
Hi,

denke mal du hast sogar 2 Möglichkeiten.

1) Poke_BLK

Auszug System Manual:
POKE_BLK(area_src:=_in_,
dbNumber_src:=_in_,
byteOffset_src:=_in_,
area_dest:=_in_,
dbNumber_dest:=_in_,
byteOffset_dest:=_in_,
count:=_in_);

Schreibt die unter "count" angegebene Anzahl von Bytes beginnend mit dem angegebenen
byteOffset des angegebenen Quelldatenbausteins, der Quell-E/A oder des
Quellspeicherbereichs in den angegebenen byteOffset des angegebenen
Zieldatenbausteins, der Ziel-E/A oder des Zielspeicherbereichs.

Beispiel:
POKE_BLK(area_src:=16#84,
dbNumber_src:=#src_db,
byteOffset_src:=#src_byte,
area_dest:=16#84,
dbNumber_dest:=#src_db,
byteOffset_dest:=#src_byte,
count:=10);
Bei den Anweisungen PEEK und POKE gelten die folgenden Werte für die Parameter
"area", "area_src" und "area_dest". Für andere Bereiche als Datenbausteine muss der
Parameter dbNumber 0 sein.
16#81 I
16#82 Q
16#83 M
16#84 DB



2) RDREC / WRREC

Auszug System Manual:
"RDREC_DB"(
req:=_bool_in_,
ID:=_word_in_,
index:=_dint_in_,
mlen:=_uint_in_,
valid=>_bool_out_,
busy=>_bool_out_,
error=>_bool_out_,
status=>_dword_out_,
len=>_uint_out_,
record:=_variant_inout_);

Mit der Anweisung RDREC lesen Sie einen Datensatz mit der Nummer INDEX
aus der Komponente, die von ID angegeben wird, z. B. aus einem
zentralen Baugruppenträger oder einer dezentralen Komponente (PROFIBUS DP
oder PROFINET IO). Geben Sie die maximale Anzahl der zu lesenden Bytes
in MLEN an. Die ausgewählte Länge des Zielbereichs RECORD muss mindestens
die Länge der von MLEN angegebenen Bytes haben

Gruß MK
 
Zuletzt bearbeitet:
Danke für Eure schnellen Antworten

@Mäuseklavier
Aber soweit ich das richtig verstanden habe, kann mit PEEK/POKE_BLK nicht konsistent auf ein Profibus / Profinet Slave geschrieben/gelesen werden (Module >= 4 Worte)

RDREC / WRREC benötigen nach meinem Wissen mehrere SPS Zyklen -> In meinem Fall nicht erwünscht

@Rupp
Ich nehme an, Du meinst folgendes (Beispiel Siemens Hilfe):
Code:
(*Abhängig vom Wert der Laufvariable i wird ein Eingangswort auf 0  gesetzt.*)
  #i:=2
 FOR #i := 2 TO 8 DO
     EW(#i) := 0  ;
 END_FOR;
Edit: Bei einer S1200 scheint das aber nicht zu funktionieren


Damit kann ich alle Module des Profibus Slaves lesen/schreiben, welche <=4 Byte gross sind.
Für die anderen Module des Slaves, z.B. 10 Worte Ausgang (konsistent über die gesamte Länge) sehe ich keine andere Lösung als über DPWR_DAT

@Alle
Nehmen wir an ich habe ein Profibus Slave mit zwei Modulen:
1. Modul "Get_Status" Eingangsadresse 256, Grösse 1 Wort
2. Modul "Get_Config" Eingangsadresse 258, Grösse 4 Worte

Das 1. Modul kann ich nun entweder mit PEEK_WORD oder EW(256) lesen
Für das 2. Modul muss ich die Funktion DPRD_DAT verwenden. Ich kann jedoch als LADDR nicht 258 (Eingangsadresse des Moduls) verwenden, sondern muss die automatisch generierte Variable "Get_Status_1" vom Typ HW_Submodule benutzen.

Kann ich mit den automatisch generierten Variablen (HW_Submodule) auch auf Module zugreifen mit Grösse <=2 Worte. Dann könnte ich alles damit abdecken.

Oder wieso funktionieren die DPRD_DAT bzw. DPWR_DAT nur mit HW_Submodule Adressen und nicht mit den Eingangs-/Ausgangsadressen der Profibus Slave Module?

Es geht mir einfach darum, dass ich an meinem Baustein, welcher alle Module (egal welche Grösse) des Profibus Slaves liest, als Eingänge entweder nur Eingangsadressen ODER HW_Submodule Variablen anschliessen kann.

Vielen Dank
 
Zuletzt bearbeitet:
Aber soweit ich das richtig verstanden habe, kann mit PEEK/POKE_BLK nicht konsistent auf ein Profibus / Profinet Slave geschrieben/gelesen werden (Module >= 4 Worte)

Habe dazu keine Aussgae gefunden.

RDREC / WRREC benötigen nach meinem Wissen mehrere SPS Zyklen -> In meinem Fall nicht erwünscht

Da hast du recht.

Mir ist nicht ganz klar warum du ein einzelnes Wort mit einer Funktion auslesen willst?

Mit den HW-Submodulen ist schon blöd, besonders wenn sie nicht editierbar (ausgegraut) sind.
Werd dem mal nachgehen. Vielleicht weis ja noch wer anders wie es optimal geht.

Gruß MK
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich möchte ja gar keine Funktionen verwenden. Aber ich sehe momentan keinen anderen Weg auf der S1200 in SCL, da das: EW(#i) := 0 ; nicht zu funktionieren scheint.

Danke für Deine Mühen
 
Habe keine 1200er bei mir aufm Platz zum Testen,
allerdings scheint das mit der HW-Kennung in der online-Hilfe bzw. in der Auswahl wohl nicht zu stimmen,
denn die kann ich ja nicht editieren. Am DPRD_DAT kann ich allerdings auch direkt ein Zahlenwert angeben, also auch die HW-E/A-Adresse.
Demnach wären die Auswahlliste mit den HW-Kennungen Blödsinn.

Vergleiche hierzu auch
Systemhandbuch (denke mal richtig):
LADDR : IN : HW_IO (Word)
Konfigurierte Startadresse im Bereich "E" des Moduls, aus dem die
Daten gelesen werden (DPRD_DAT) Konfigurierte Startadresse aus dem Prozessabbild der Ausgänge des
Moduls, in das die Daten geschrieben werden (DPWR_DAT)
Die Adressen müssen im Hexadezimalformat eingegeben werden
(Beispiel: eine Eingangs- oder Ausgangsadresse von 100 bedeutet:
LADDR:=W#16#64).

online-Hilfe (denke mal falsch)
LADDR : Input : HW_IO (WORD)
Hardware-Kennung der Baugruppe, aus der gelesen werden soll. Wenn Sie auf den Bausteinparameter LADDR klicken, werden alle adressierbaren Komponenten mit ihrer HW-Kennung in einer Klappliste zur Auswahl angeboten.

In SCL kannst du also eine HW_IO-Variable definieren(indizieren) und die entsprechende E/A-Adresse zuweisen.
Das zu lesende/schreibende Volumen wird durch den RECORD definiert.

RECORD : OUT : Variant
Zielbereich der gelesenen Anwenderdaten (DPRD_DAT) oder
Quellbereich der zu schreibenden Anwenderdaten (DPWR_DAT). Dieser
Bereich muss genau so groß sein, wie Sie für das ausgewählte Modul mit
STEP 7 konfiguriert haben. Nur der Datentyp Byte ist zulässig.

Gruß MK
 
Hallo MK,

Leider funktioniert das mit der Ausgangsadresse des Moduls nicht.

Modul mit Ausgangsadresse 102 (16#66):
Module.png

DPWR_DAT wirft Fehler 16#8090:
Fehler_8090_DPWR_DAT.jpg

Aus Siemens Informationssystem:
8090

  • Für die angegebene HW-Kennung haben sie keine Baugruppe projektiert, oder
  • Sie haben die Einschränkung über die Länge der konsistenten Daten nicht beachtet, oder
  • Sie haben als Adresse am Parameter LADDR keine HW-Kennung angegeben.

Die Einschränkung der Länge muss ich nicht beachten, die stimmt bei mir. Ich will ein Array[0..9] of Word schreiben und das Modul ist 10 Worte gross. Die Variable an LADDR ist vom Typ HW_IO.

Es funktioniert nur, wenn ich als Adresse dieses selbstgenerierte HW_Submodule verwende:
HW_Submodule.png

Und die ist 16#011A, wieso auch immer...

Danke für dein Zeit.

Gruss Florian
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So, ich lese/schreibe halt nun bis ich eine andere Lösung habe alle Module (auch Wort und Doppelworte) mit DPRD_DAT / DPWR_DAT. Ist zwar nicht schön, aber damit kann ich alle Module mit den automatisch generierten HW_Submodule Adressen adressieren...

Falls noch jemand eine andere Lösung findet... Wäre toll.

Gruss Florian

Nachtrag:

Siemens gibt auch selbst im Handbuch an, dass DPRD_DAT / DPWR_DAT auch für Bereiche >=1 Byte verwedet werden können.
Systemhandbuch S7-1200 (englisch, Kapitel 8.3.5):
The CPU supports up to 64 bytes of consistent data. For consistent data areas greater than
64 bytes, the DPRD_DAT and DPWR_DAT instructions must be used. If required, these
instructions can be used for data areas of 1 byte or greater. If access is rejected, error code
W#16#8090 will result.
 
Zuletzt bearbeitet:
Der Beitrag ist schon etwas älter aber wie wär's damit (ist allerdings nicht konsistent)

Code:
#i := 0;
#x := 0;
FOR #i := 2 TO 8 BY 2 DO
#x := #x +1;  
   POKE(area:=16#82,                                                      // Bereich 'Ausgänge'
     dbNumber:=0,                                                         // Kein DB
     byteOffset:=#Adr_ANAU+#i,                                            // ANAU Adresse aus Vorgabe + Offset i
     value:=INT_TO_WORD(#V_Soll[#x]));                                    // Sollwert Array
END_FOR;
 
Zurück
Oben