IN_OUT mit Indirekter Adressierung

SCM

Level-1
Beiträge
335
Reaktionspunkte
33
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!
Hab ein kleines Problem mit dem Versatz als Multiinstanzfähigen Baustein.
Es soll ein Einganswert eingelesen werden und dann schleifenmäßig verteilt werden.Wenn ich in der Multiinstanz schaue seh ich das der Erste wert auf DI 226.0 geschrieben wird in wirklichkeit ist er aber bei DI 228.0.
Wo kommt der versatz her?Kann man nicht auf in_out veriablen lesen/Schreiben? Kann mir da jemand helfen?

Hier mal mein Programm bisher


L #CNT //Aktueller Schrittzähler
T #CHANNEL //Ausgang für Adressierung Multiplexer
U #TAKT //Abtasttakt
FP #_flanke[1]
SPBN m001
TAR1 #RETTAR1 //Adressregister retten
TAR2 #RETTAR2 //Adressregister retten
LAR1 P##TEMP //Pointer auf erste relevante Daten setzen
L #CNT
L 4
*I
SLW 3
+AR1 //Offset aktueller schritt mit einrechnen
L #RETTAR2 //Adressregister 2 adieren für Multiinstanzfähigkeit
+AR1
L #INPUT //Eingangswert einlesen
T DID [AR1,P#0.0] //Auf Position schreiben die im AR1 steht
L DID [AR1,P#64.0] //Min auswerten
<R
SPBN min
TAK
T DID [AR1,P#64.0]
min: L DID [AR1,P#0.0] //Max auswerten
L DID [AR1,P#128.0]
>R
SPBN max
TAK
T DID [AR1,P#128.0]
max: L #CNT //Schrittzähler laden
INC 1 //um eins erhöhen
T #CNT //wieder in schrittzähler variable schreiben
LAR1 #RETTAR1 //Adressregister restaurieren
LAR2 #RETTAR2 //Adressregister restaurieren
m001: L #CNT //Schrittzähler auf überlauf prüfen
L #LOOPCNT
>I
SPBN ende
L #CNT
L 0
T #CNT
ende: SET //Baustein immer mit vke 1 verlassen damit ENO immer 1 ist
SAVE
Mfg Mario
 
Zuletzt bearbeitet:
Hab den Baustein jetzt etwas angepasst mit dieser Variante funktioniert er!Nur würde mich interessieren warum er sonst nicht funktioniert hat?!
Hab hier erstmal die ganzen Werte auf statische Variablen gelegt und dann mit Blockmove an den Ausgang übertragen!

Hier der aktuelle code:
L #CNT
T #CHANNEL
U #TAKT
FP #_flanke[1]
SPBN m001
TAR1 #RETTAR1
TAR2 #RETTAR2

LAR1 P##TEMP
L #CNT
L 4
*I
SLW 3 //Offset mit einrechnen
L #RETTAR2
+D
+AR1
L #INPUT
T DID [AR1,P#0.0]
L DID [AR1,P#64.0]
<R
SPBN min
TAK
T DID [AR1,P#64.0]
min: L DID [AR1,P#0.0]
L DID [AR1,P#128.0]
>R
SPBN max
TAK
T DID [AR1,P#128.0]
max: LAR1 #RETTAR1
LAR2 #RETTAR2

L #CNT
INC 1
T #CNT

CALL "BLKMOV"
SRCBLK :=#TEMP
RET_VAL:=#_int
DSTBLK :=#TEMP_OUT

m001: L #CNT
L #LOOPCNT
>I
SPBN ende
L #CNT
L 0
T #CNT
ende: SET
SAVE
Vielleicht kann ja noch jemand sagen warum es anders nicht passt!?

Mfg Mario
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Für Code gibt es Code-Tags, dann kann man den Spagetticode ein wenig lesen. Kommentare wären auch von Vorteil. Und wenn du in deinem 2. Code die Änderungen farbig gekennzeichnet hättest (+Codtags), dann würde vielleicht auch mal jemand drüberschauen. Versuchs mal selbst und du wirst dich nicht mehr wundern, warum keiner antwortet, dafür ist den meisten Leuten ihre Zeit zu schade.
 
Für Code gibt es Code-Tags, dann kann man den Spagetticode ein wenig lesen. Kommentare wären auch von Vorteil. Und wenn du in deinem 2. Code die Änderungen farbig gekennzeichnet hättest (+Codtags), dann würde vielleicht auch mal jemand drüberschauen. Versuchs mal selbst und du wirst dich nicht mehr wundern, warum keiner antwortet, dafür ist den meisten Leuten ihre Zeit zu schade.


Hallo!
Hast ja recht hab nun die Beiträge angepasst!

Mfg
 
Hallo,
ich muß zugeben, dass ich durch das Programm auch nicht durchsteige - so oder so ...

Bei einer Multiinstanz kompensiert man den Versatz normalerweise durch Addieren des AR2-Registers auf den Pointer. So etwas in der Art machst du aber schon.
Was mir hier unklar ist : du sprichst von einer IN_OUT-Variablen. Das sind normalerweise Pointer. Ich sehe gar nicht, wo du die Quell-Adresse des Pointers lädst ...
Welches ist die IN_OUT-Variable ?

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich muß zugeben, dass ich durch das Programm auch nicht durchsteige - so oder so ...

Bei einer Multiinstanz kompensiert man den Versatz normalerweise durch Addieren des AR2-Registers auf den Pointer. So etwas in der Art machst du aber schon.
Was mir hier unklar ist : du sprichst von einer IN_OUT-Variablen. Das sind normalerweise Pointer. Ich sehe gar nicht, wo du die Quell-Adresse des Pointers lädst ...
Welches ist die IN_OUT-Variable ?

Gruß
Larry

Hallo!
Ja es wird immer das adr2 dazu gezählt und noch mal der offset für den aktuellen schritt!
LAR1 P##TEMP
mit diser anweisung setze ich auf die ersten relevanten daten!Ist in der in_out deklaration und ist ein udt.

Mfg
 
OK ... verstanden.
An der Adresse steht dann aber nur der Pointer, der auf den Quell-Bereich des UDT zeigt. Du mußt jetzt also den Pointer decodieren ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie ich es geschrieben habe :
Du verweist an der Stelle auf einen Pointer. Lad dir mal aus der Step7-Hilfe den Aufbau des Pointer. Du mußt nun also die Adresse, die in dem Pointer hinterlegt ist, in dein AR1 laden und kannst dann auf den echten Datenbereich zugreifen.
Schau dir mal den Instanz-DB deines FB an. Dort, wo der IN-OUT-Parameter steht wird nur ein 6 Byte großer Bereich reserviert und nicht die Größe deines UDT.

Gruß
Larry
 
Wie ich es geschrieben habe :
Du verweist an der Stelle auf einen Pointer. Lad dir mal aus der Step7-Hilfe den Aufbau des Pointer. Du mußt nun also die Adresse, die in dem Pointer hinterlegt ist, in dein AR1 laden und kannst dann auf den echten Datenbereich zugreifen.
Schau dir mal den Instanz-DB deines FB an. Dort, wo der IN-OUT-Parameter steht wird nur ein 6 Byte großer Bereich reserviert und nicht die Größe deines UDT.

Gruß
Larry
Also müsste ich das dann wieder mit SLD3 umwandeln?
Oder gehts auch schon wenn ich statt:
T DID [AR1,P#0.0]
T D[AR1,P#0.0] schreibe?
Mfg
 
... diese Sache überlasse ich normalerweise dem SCL-Compiler ...

Aber mal so "quick-and-dirty" :
Code:
LAR1 P##TEMP
TAR2
+AR1
L W[AR1,p#0.0]
T #DB_Nummer   // TEMP-Variable vom Typ WORD
L D[AR1,P#2.0]
T #QPointer       // TEMP-Variable vom Typ DWORD
 
AUF DB [DB_Nummer]
L #QPointer
LAR1                 // nun solltest du im AR1-Register die korrekte Adresse haben
probier das mal ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... diese Sache überlasse ich normalerweise dem SCL-Compiler ...

Aber mal so "quick-and-dirty" :
Code:
LAR1 P##TEMP
TAR2
+AR1
L W[AR1,p#0.0]
T #DB_Nummer   // TEMP-Variable vom Typ WORD
L D[AR1,P#2.0]
T #QPointer       // TEMP-Variable vom Typ DWORD
 
AUF DB [DB_Nummer]
L #QPointer
LAR1                 // nun solltest du im AR1-Register die korrekte Adresse haben
probier das mal ...

Gruß
Larry

Das haut auch nicht hin!
Jetzt hab ich immer noch die falsche stelle im AR1 stehen!

Jetzt passts war noch beim Transferieren auf DIW das passt dann natürlich nimmer weil der db aufgeschlagen wird!
Mfg
 
Zuletzt bearbeitet:
... ich habe es jetzt gerade mal meinem SCL-Compiler übergeben ...
Der macht das davon :
Code:
LAR1 P##TEMP
TAR2
+AR1
L DIW[AR1,p#0.0]
T #DB_Nummer   // TEMP-Variable vom Typ WORD
L DID[AR1,P#2.0]
T #QPointer       // TEMP-Variable vom Typ DWORD
 
AUF DB [DB_Nummer]
L #QPointer
LAR1                 // nun solltest du im AR1-Register die korrekte Adresse haben
... dann teste das doch bitte noch mal ...
 
Zuletzt bearbeitet:
... ich habe es jetzt gerade mal meinem SCL-Compiler übergeben ...
Der macht das davon :
Code:
LAR1 P##TEMP
L DIW[AR1,p#0.0]
T #DB_Nummer   // TEMP-Variable vom Typ WORD
L DID[AR1,P#2.0]
T #QPointer       // TEMP-Variable vom Typ DWORD
 
AUF DB [DB_Nummer]
L #QPointer
LAR1                 // nun solltest du im AR1-Register die korrekte Adresse haben
... dann teste das doch bitte noch mal ...

Hab das jetzt mal so gemacht dann funktionierts nimmer!
Es steht schon beim ersten befehl die falsche db nummer!
Hast du Temp als IN_OUT variable vergeben?

mfg
 
Wo kommen denn deine Daten, die du der Schnittstelle übergibst, ursprünglich her ?
Den Wert den ich übergebe ist eine IN Variable und in diesem fall ein Byte Temperatureingang von RTD Modul!
Es stellt einen Multiplexer dar!Ich habe ein Gerät das 16 Temperatur eingänge hat und einen Ausgang!Dem Gerät sende ich eine Adresse und diesen wert von dem Adressierten Kanal bekomme ich zurück!
Mfg
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... ich habe es jetzt gerade mal meinem SCL-Compiler übergeben ...
Der macht das davon :
Code:
LAR1 P##TEMP
TAR2
+AR1
L DIW[AR1,p#0.0]
T #DB_Nummer   // TEMP-Variable vom Typ WORD
L DID[AR1,P#2.0]
T #QPointer       // TEMP-Variable vom Typ DWORD
 
AUF DB [DB_Nummer]
L #QPointer
LAR1                 // nun solltest du im AR1-Register die korrekte Adresse haben
... dann teste das doch bitte noch mal ...


Also dieser Code funktioniert soweit!
Ohne das man den DB aufmachen muss wirds nicht gehen oder?

Mfg
 
Sodale hier noch mal der Code der funktioniert
Code:
      L     #CNT                        //Aktueller Schrittzähler
      T     #CHANNEL                    //Ausgang für Adressierung Multiplexer
      U     #TAKT                       //Abtasttakt
      FP    #_flanke[1]
      SPBN  m001

      TAR1  #RETTAR1                    //Adressregister retten
      TAR2  #RETTAR2                    //Adressregister retten

      LAR1  P##TEMP                     //Pointer auf erste relevante Daten setzen
      L     #RETTAR2                    //Adressregister 2 addieren für Multiinstanzfähigkeit
      +AR1  
      L     W [AR1,P#0.0]               //DB nummer auslesen
      T     #DB_NMB                     //Eintragen
      L     D [AR1,P#2.0]               //Pointer auslesen
      T     #QPOINTER                   //Eintragen

      AUF   DB [#DB_NMB]                //DB aufschlagen
      L     #QPOINTER                   //Pointer laden ins AR1
      LAR1  
      L     #CNT                        //Aktueller Schritt bzw. Temperaturwert
      L     2                           //Schrittweite 2 weil die Werte INT sind
      *I    
      SLW   3                           //Ins Pointerformat wandeln
      +AR1                              //Offset aktueller schritt mit einrechnen
      L     #INPUT                      //Eingangswert einlesen
      T     W [AR1,P#0.0]               //Auf Position schreiben die im AR1 steht
      L     W [AR1,P#32.0]              //Min auswerten
      <I    
      SPBN  min
      TAK   
      T     W [AR1,P#32.0]
min:  L     W [AR1,P#0.0]               //Max auswerten
      L     W [AR1,P#64.0]
      >I    
      SPBN  max
      TAK   
      T     W [AR1,P#64.0]
max:  L     #CNT                        //Schrittzähler laden
      INC   1                           //um eins erhöhen
      T     #CNT                        //wieder in schrittzähler variable schreiben

      LAR1  #RETTAR1                    //Adressregister restaurieren
      LAR2  #RETTAR2                    //Adressregister restaurieren

m001: L     #CNT                        //Schrittzähler auf überlauf prüfen
      L     #LOOPCNT
      >I    
      SPBN  ende
      L     #CNT
      L     0
      T     #CNT
ende: SET                               //Baustein immer mit vke 1 verlassen damit ENO immer 1 ist
      SAVE

Mfg Mario
 
Ich würde es so machen - dann bist du unabhängig davon, von wo die Daten kommen. Der eine (ggf. unnötige) Befehl frißt aber auch kein Brot ...
 
Zurück
Oben