FB mit lokalen Variablen schreiben

Miffi

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

ich möchte einen FB mit lokalen Variablen schreiben, der Daten in einen Datensatz (DBWx.x) schreibt.

Mit folgender Zeile

T DBW[#MD1] //MD1 v. Typ DINT

geht es nicht. Wenn ich MD1 absolut verwende geht es. Aber es soll ja lokal sein. Weiß jemand Rat?
 
:confused:
Im Stat-Bereich eine Variable vom Typ DInt anlegen und dann im Programm mit

T #myDInt

den Wert in den zugehörigen IDB schreiben ... hast du das gemeint?
 
Meinst du mit Lokalen Variablen den Stat - Bereich?
Dein Adressenoperand (die Variable wo dein Pointer drinn ist) kann nicht im Stat Bereich abgelegt werden wenn dein Baustein Multiinstanzfähig ist, da es sonst Probleme mit den Adressregistern gibt.
Du kannst entweder deinen Bausten nicht Multiinstanzfähig machen oder den Adressoperanden im temp Bereich ablegen.

godi
 
DB1 kann - sagen wir mal - 10 Werte des Typs INT aufnehmen.

FB1 soll die Werte (z. B: 2345, 167, 21982, 1200, ...) in DB1 schreiben.

FB1 wird nur halt mit lokalen Variablen deklariert!

...
AUF #DATENBAUSTEIN
L #DATEN
T DBW[#MD1]
...

wobei der Fehler auftritt bei #MD1
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Meinst du mit Lokalen Variablen den Stat - Bereich?
Dein Adressenoperand (die Variable wo dein Pointer drinn ist) kann nicht im Stat Bereich abgelegt werden wenn dein Baustein Multiinstanzfähig ist, da es sonst Probleme mit den Adressregistern gibt.
Du kannst entweder deinen Bausten nicht Multiinstanzfähig machen oder den Adressoperanden im temp Bereich ablegen.

godi


Ja, das ist es. Danke!
 
Ja, das ist es. Danke!
Was denn jetzt genau? Hast du den Aderssoperanden im Temp abgelegt?
Dein Problem ist gelöst, aber keiner weiß genau wo das Problem lag...

190B hat dich 2mal gebeten den Baustein zu zeigen oder genauer zu werden.
Sinn und Zweck eines solchen Threads ist es unter anderem, das andere Nutzer oder Besucher
des Forums mit Schlagworten diese Posts finden und ihr Problem anhand der dort zu findenen Informationen
eigenständig lösen können. Außerdem möchten auch diejenigen die dir geholfen haben ein ordentliches Feedback.
Sei bitte allen gegenüber so fair.

Danke, Toki
 
Hallo,

es tut mir leid, ich war so in Eile, 190B hat geschrieben, dass ich den Baustein hier reinstellen soll ... aber ich wusste nicht wie.

Wie ich schon bereits geschrieben habe: ich möchte einen FB mit lokalen Variablen schreiben, der Daten in einen Datenbaustein (DBxy.DBWxy) schreibt.


// Daten in Baustein schreiben geht so nicht:

AUF #DATENBAUSTEIN
L #DATEN
T DBW[#MD1]
L #MD1
L p#2.0
+D
T #MD1
L #MD1
L #ENDE
==D
SPB ENDE

// weil MD1 als STAT eingestellt war.

Dann habe ich - wie von Godi gesagt - MD1 als TEMP eingestellt und das hat funktioniert.

Aber warum??? Das habe ich noch nicht verstanden. Ich dachte, MD1 ist nur 1 Zyklus gültig, wenn ich es als TEMP einstelle? Wie konnte der Wert von MD1 bis zum Schluss erhalten bleiben ... ein Phänomen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
das was Godi schreibt erscheint mir in diesem Zusammenhang nicht logisch. Du greifst ja nicht indirekt auf deine Variable "#MD1" zu (das ist übrigens ein blöder Name, da er die Verwendung eines Merker-Doppelwortes vorgaukelt).
Ist diese Variable den in beiden Fällen (TEMP-Bereich und STAT-Bereich) als DINT deklariert ? Ich kenne es so, dass diese Variable als DWORD deklariert sein muß - ich bin allerdings gerade nicht in der Lage, dass in der Software gegenzuchecken ...

Was passiert wenn #MD1 <> #Ende ist ?
Bei der Abfrage ist es übrigens sinnig nicht ==D sondern besser >=D hinzuschreiben ...

Gruß
Larry
 
Dann habe ich - wie von Godi gesagt - MD1 als TEMP eingestellt und das hat funktioniert.

Aber warum??? Das habe ich noch nicht verstanden. Ich dachte, MD1 ist nur 1 Zyklus gültig, wenn ich es als TEMP einstelle? Wie konnte der Wert von MD1 bis zum Schluss erhalten bleiben ... ein Phänomen

Natürlich ist dein #MD1 nur ein Zyklus gültig! Du musst bevor du lesend auf #MD1 zugreifst unbedingt schreibend auf #MD1 zugreifen!
Warum es funktioniert hat: Du verwendest in keinem anderem Baustein mit der selben Interrup Priorität Lokale Daten.

@Larry
Ich habe gerade mein altes Buch hervorgekramt (Automatisieren mit Step7 in AWL und SCL, 4 Auflage) und da steht auf Seite 417:
In Funktionsbausteinen können Sie Instanzdaten als Adressenoperanden nur dann einsetzen, wenn Sie den Baustein als CODE_VERSION1-Baustein übersetzen.(nicht "multiinstanzfähig")
Der Grund warum steht leider nicht dabei.
Ich denke mal das die speicherindirekte Adressierung intern auch gleich wie die registerindirekte Adressierung funktioniert und somit würde es bei einer Multiinstanz Probleme mit den Adressregistern geben.

godi
 
// Daten in Baustein schreiben geht so nicht:
[...]
// weil MD1 als STAT eingestellt war.

Dann habe ich - wie von Godi gesagt - MD1 als TEMP eingestellt und das hat funktioniert.
Warum STAT nicht geht? Weil der AWL-Compiler es nicht kann. Und Siemens extra dokumentiert, daß es nicht zulässig ist:
Hilfe zu AWL schrieb:
Speicherindirekte Adressierung
[...]
Der Pointer muß für die speicherindirekte Adressierung in einem der folgenden Bereiche gespeichert werden:
· M - Merker
· L - Lokaldaten
· D - Datenbaustein (DB oder DI)
· STAT - Statische Daten (nicht bei multiinstanzfähigen Bausteinen)

Wenn der Pointer #MD1 unbedingt STAT sein muß, dann kann er auch extra nur für die speicherindirekte Operation auf ein TEMP-DWORD umkopiert werden:
Code:
L #MD1
T #TEMP_PTR

L #DATEN
AUF #DATENBAUSTEIN
T DBW[#TEMP_PTR]

Ich dachte, MD1 ist nur 1 Zyklus gültig, wenn ich es als TEMP einstelle? Wie konnte der Wert von MD1 bis zum Schluss erhalten bleiben ... ein Phänomen
Eine TEMP-Variable ist gültig von der ersten Zuweisung bis zum Ende des Bausteins. Danach verliert sie ihren Inhalt und muß im nächsten Durchlauf erneut einen Wert zugewiesen bekommen, bevor ihr Inhalt benutzt werden kann.

In Deinem Programm-Fragment benutzt Du #MD1 in der 3. Zeile bevor Du #MD1 in der 7. Zeile etwas zuweist - das dürfte mit #MD1 als TEMP nicht funktionieren. Es sei denn, Du hast noch Code mit der Zuweisung vor dem hier gezeigten Code.


190B hat geschrieben, dass ich den Baustein hier reinstellen soll ... aber ich wusste nicht wie.
Programmcode in einen Beitrag einfügen: den Code-Text zwischen [CODE]-Tags einfügen. Dazu im Beitragseditor den #-Button benutzen. Oder als Textdatei an den Beitrag anhängen (hochladen).

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich kenne es so, dass diese Variable als DWORD deklariert sein muß - ich bin allerdings gerade nicht in der Lage, dass in der Software gegenzuchecken ...
STEP7-AWL läßt für Pointer im Doppelwortformat DWORD und DINT zu, und außerdem auch !!! REAL, Time, Time_Of_Day :ROFLMAO: - anscheinend alles, was 32 Bit groß ist. Eigentlich ist keiner der Datentypen 100% korrekt, doch DWORD kommt dem Zweck noch am nächsten. Ich verwende immer nur DWORD.

Harald
 
Natürlich ist dein #MD1 nur ein Zyklus gültig! Du musst bevor du lesend auf #MD1 zugreifst unbedingt schreibend auf #MD1 zugreifen!
Warum es funktioniert hat: Du verwendest in keinem anderem Baustein mit der selben Interrup Priorität Lokale Daten. godi

Das ist der Grund, warum die temporäre Index-Variable weiter ihre Gültigkeit beibehält? Soll aber lt. Definition nicht sein dürfen oder?
 
In Deinem Programm-Fragment benutzt Du #MD1 in der 3. Zeile bevor Du #MD1 in der 7. Zeile etwas zuweist - das dürfte mit #MD1 als TEMP nicht funktionieren. Es sei denn, Du hast noch Code mit der Zuweisung vor dem hier gezeigten Code.
Programmcode in einen Beitrag einfügen: den Code-Text zwischen [CODE]-Tags einfügen. Dazu im Beitragseditor den #-Button benutzen. Oder als Textdatei an den Beitrag anhängen (hochladen).

Harald

Ja, die Index-Variable ist vollkommen TEMP. Ich poste mal den kompletten Code hier mit OB1 und ausformulierten Variablen zum besseren Verständnis:

Code:
// OB1: 



U     E      0.0
      =     L     20.0
      BLD   103
      U     M    255.1
      =     L     20.1
      BLD   103
      CALL  FB     1 , DB1
       start_reset  :=L20.0
       takt         :=L20.1
       datenbaustein:=DB100
       daten        :=850
       db_max       :=6400
       led_ende     :=A0.0




// FB1: 

//Es soll der Taktmerker z. B. ein M255.1 verwendet werden, um zur eingestellten 
//Zeit die abgeholten Daten (INT-Zahl) um 1 zu erhöhen und in einen 
//lobal-Datenbaustein einzutragen, also x+1 bis x+max. Die originalen Daten 
//(INT-Zahl) sollen nicht verändert werden.

// #datenbaustein: einen schon erstellen Datenbaustein angeben
// #db_max:  max. Anzahl der Datensätze in INT (Bitweise)
// #led_ende: LED leuchtet, sobald zum ersten Mal DB-Ende erreicht wird
// #daten: irgendeine INT-Zahl als Anfangswert, hier einfach 850 

IN:
start_reset, BOOL
takt, BOOL
datenbaustein, BLOCK_DB
daten, INT
db_max, INT

OUT:
led_ende, BOOL

STAT:
mw_dateninhalt, INT
m_index_anfang, BOOL
m_daten_geholt, BOOL


TEMP:
m_flanke_takt, BOOL
md_db_index, DINT

// Programm starten:

      UN    #start_reset                
      SPB   NULL


      L     #md_db_index
      L     0
      ==D   
      S     #m_index_anfang


      U     #start_reset
      U     #takt
      FP    #m_flanke_takt
      U     #m_index_anfang
      SPBN  ENDE


      UN    #m_daten_geholt
      SPB   HOLE                       


      L     #mw_dateninhalt             
      L     1                         
      +I    
      T     #mw_dateninhalt
      AUF   #datenbaustein
      L     #mw_dateninhalt             
      T     DBW [#md_db_index]    
      L     #md_db_index
      L     16                         
      +D    
      T     #md_db_index


      L     #md_db_index
      L     #db_max                
      ==D   
      R     #m_index_anfang
      S     #led_ende
      SPB   NULL                      
      BE    


HOLE: L     #daten
      T     #mw_dateninhalt
      S     #m_daten_geholt
      R     #led_ende
      BE    


NULL: L     0
      T     #md_db_index
      L     #daten
      T     #mw_dateninhalt


ENDE: BE
 
Zurück
Oben