Anzahl der möglichen Multiinstanzen durch Befehl +AR1 begrenzt.

RONIN

Level-3
Beiträge
2.508
Reaktionspunkte
760
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute!

In einem meiner FB's verwende ich die altbekannte Methode der Übergabe eines Datenbereichs an den FB via Any-Pointer.
Der Pointer wird dann im FB umkopiert, kurz aufbereitet und dann an einen SFC20 übergeben.

Code:
      TAR1  #SaveAR1                    //Adressregister sichern
      TAR2  #SaveAR2

      LAR1  P##P_Data                   //P_Data aus IN-Bereich nach TEMP kopieren
      L     #SaveAR2
      +AR1  
      LAR2  P##P_Data_tmp

      L     D [AR1,P#0.0]               //Zeiger kopieren
      T     LD [AR2,P#0.0]
      L     D [AR1,P#4.0]
      T     LD [AR2,P#4.0]
      L     W [AR1,P#8.0]
      T     LW [AR2,P#8.0]

      L     LW [AR2,P#2.0]              //Zeiger umwandeln auf Hälfte 1 des Ursprungszeigers
      L     2                           //Enstspricht SX-Bereich des vorangegangenen Bausteins
      /I    
      T     LW [AR2,P#2.0]

      LAR1  #SaveAR1                    //Adressregister wiederherstellen
      LAR2  #SaveAR2

Diese Variante funktioniert tadellos, solange bis der Multiinstanz-Offset beim Aufruf die Zahl 4095 überschreitet. Anscheinend ergibt sich das Problem
in der Verwendung des Befehls +AR1, welcher einen Offset auf das AR1 aufaddiert. Hier verwendet um den Multiinstanz-Offset aufzuaddieren.

Anscheinend funktioniert der +AR1 Befehl nur bis zu einem Wert von 4095.
Die Ursache wird wohl hier liegen: (Auszug aus der Hilfe zum Befehl +AR1)
"+AR1: Die Ganzzahl (16 Bit), die zum Inhalt von AR1 addiert werden soll, wird durch den Wert in AKKU1-L angegeben. Zulässig sind Werte von -32768 bis +32767"
Wenn ich das richtig lese wird eine 16Bit Zahl als Pointer interpretiert und dann aufgerechnet.
16Bit - Vorzeichen -> 15Bit - 3Bit Bitadresse -> 12Bit: 4095

Soweit eigentlich klar: Meine Frage jetzt nur.... wie könnte man das umgehen? Ich möchte nicht jedes mal eine neuen FB anfangen nur weil mir die Multiinstanzen ausgehen.
 
Versuch mal:

Code:
      TAR1  #SaveAR1                    //Adressregister sichern
      TAR2  #SaveAR2

     [COLOR=#ff0000] L     P##P_Data                   //P_Data aus IN-Bereich nach TEMP kopieren
      L     #SaveAR2
      +D
      LAR1  [/COLOR]
      LAR2  P##P_Data_tmp

      L     D [AR1,P#0.0]               //Zeiger kopieren
      T     LD [AR2,P#0.0]
      L     D [AR1,P#4.0]
      T     LD [AR2,P#4.0]
      L     W [AR1,P#8.0]
      T     LW [AR2,P#8.0]

      L     LW [AR2,P#2.0]              //Zeiger umwandeln auf Hälfte 1 des Ursprungszeigers
      L     2                           //Enstspricht SX-Bereich des vorangegangenen Bausteins
      /I    
      T     LW [AR2,P#2.0]

      LAR1  #SaveAR1                    //Adressregister wiederherstellen
      LAR2  #SaveAR2
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Oh man bin ich blö..... :icon_confused:

Ich war so auf den +AR1 Befehl fixiert. Darauf hätt ich nun wirklich selber kommen können.

Danke!
 
..Diese Variante funktioniert tadellos, solange bis der Multiinstanz-Offset beim Aufruf die Zahl 4095 überschreitet. Anscheinend ergibt sich das Problem
in der Verwendung des Befehls +AR1, welcher einen Offset auf das AR1 aufaddiert. Hier verwendet um den Multiinstanz-Offset aufzuaddieren.

Anscheinend funktioniert der +AR1 Befehl nur bis zu einem Wert von 4095.
Die Ursache wird wohl hier liegen: (Auszug aus der Hilfe zum Befehl +AR1)

Wenn ich das richtig lese wird eine 16Bit Zahl als Pointer interpretiert und dann aufgerechnet.
16Bit - Vorzeichen -> 15Bit - 3Bit Bitadresse -> 12Bit: 4095

Soweit eigentlich klar: Meine Frage jetzt nur.... wie könnte man das umgehen? Ich möchte nicht jedes mal eine neuen FB anfangen nur weil mir die Multiinstanzen ausgehen.


Darüber sind andere auch schon drüber gestolpert ;) .

http://www.sps-forum.de/showthread.php/17397-Adressberechnung-AR2?p=113925&highlight=+AR1#post113925
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja so muss es dann ausschaun!

Code:
 TAR1  #SaveAR1                    //Adressregister sichern
      TAR2  #SaveAR2

      L     P##P_Data                   //P_Data aus IN-Bereich nach TEMP kopieren#
      L     #SaveAR2
      UD    DW#16#FFFFFF                //Bereichskennung aus SaveAR2 ausmaskieren
      +D    
      LAR1

Getestet und funktioniert: :eek:

EDIT:

Code:
      TAR1  #SaveAR1                    //Adressregister sichern
      TAR2  #SaveAR2

       LAR1     #SaveAR2               <- Hier steht der Große Wert.... > 4095
       L     P##P_Data                   <- Hier steht der Kleine Wert der da der AnyPointer ja im IN-Bereich des FB's liegt wohl er wohl nie den Wert 4095 überschreiten....  
       +AR1

So wärs auch gegangen, einfach die beiden Zeilen vertauschen. Manchmal steht mal halt wirklich auf der Leitung. :s22:


EDIT:
Die wohl beste Variante (z.b. wegen dem Problem ein Beitrag weiter unten) findet man hier
http://www.sps-forum.de/simatic/63603-pointer-ueber-bausteinschnittstelle-2.html#post481732
 
Zuletzt bearbeitet:
EDIT:

Code:
      TAR1  #SaveAR1                    //Adressregister sichern
      TAR2  #SaveAR2

       LAR1     #SaveAR2               <- Hier steht der Große Wert.... > 4095
       L     P##P_Data                   <- Hier steht der Kleine Wert der da der AnyPointer ja im IN-Bereich des FB's liegt wohl er wohl nie den Wert 4095 überschreiten....  
       +AR1

So wärs auch gegangen, einfach die beiden Zeilen vertauschen.
Vorsicht: So herum hat man aber nachher in AR1 die Bereichskennung "DB" statt "DI" (*) was nicht ganz richtig ist.
Beim Eintritt in einen FB zeigen DI- und DB-Register beide auf den Instanz-DB. Der Code funktioniert zunächst.
Doch macht man die Adress-Berechnung nachdem das DB-Register verändert wurde (**) dann greift man mit "L D [AR1,P#0.0]" nicht mehr auf den FB-Eingangsparameter im IDB zu. (mit "L DID [AR1,P#0.0]" wäre man auf der sicheren Seite)

(*) weil der Instanzoffset in AR2 die Bereichskennung "DB" hat und +AR1 die in AR1 vorhandene Bereichskennung nicht verändert
(**) z.B. einfach durch einen vollqualifizierten DB-Zugriff: L "GlobalDB".VariableX

Harald
 
Zurück
Oben