- Beiträge
- 22.003
- Reaktionspunkte
- 6.842
-> Hier kostenlos registrieren
Funktioniert nur zufällig!
Dein Code funktioniert nur, wenn die Instanz im IDB an Adresse DBX0.0 beginnt. Sobald man die Instanz als Multiinstanz in einem Mutter-FB benutzt, dann ist das meistens nicht mehr der Fall. Dann muß zur relativen Adresse in dieser Instanz noch der Multiinstanz-Offset (Offset dieser Instanz im Mutter-IDB) addiert werden. Den Multiinstanz-Offset bekommt die Instanz beim Aufruf im Adressregister AR2 als P#DBXn.0 mitgeteilt. Bei nicht-multiinstanzfähigen FB enthält AR2 immer P#DBX0.0
Bei allen Zugriffen auf Instanzvariablen gehen multiinstanzfähige FB davon aus, daß im DI-Register (DINO) und im Adressregister AR2 die Anfangsadresse seiner Instanz stehen, deshalb kann man nicht auf die eigenen Instanzvariablen zugreifen, solange das DI-Register oder AR2 verändert sind.
Details siehe z.B. die Hilfe zu STEP7 > Hinweise zur Änderung von Register-Inhalten
Pointer auf eine FB-(Multi-)Instanzvariable erstellen (FB multiinstanzfähig und FB nicht-multiinstanzfähig):
Code:
//Pointer auf Instanzvariable InstVar erstellen (Variable in Bausteinparametern oder Static)
L P##InstVar // relative Adresse der #InstVar in dieser Instanz (Kennung DI)
TAR2 // Offset dieser Instanz (Kennung DB) im IDB
UD DW#16#FFFFFF // Bereichskennung (DB) ausblenden
+D
LAR1 // AR1: absolute Adresse #InstVar im IDB (Kennung DI)
//funktioniert auch so 'rum
TAR2 // Offset dieser Instanz (Kennung DB) im IDB
UD DW#16#FFFFFF // Bereichskennung (DB) ausblenden
L P##InstVar // relative Adresse der #InstVar in dieser Instanz (Kennung DI)
+D
LAR1 // AR1: absolute Adresse #InstVar im IDB (Kennung DI)
Code:
L P##TempVar // relative Adresse der #TempVar in TEMP (Kennung L)
LAR1 // AR1: relative Adresse #TempVar in TEMP (Kennung L)
//funktioniert auch kurz
LAR1 P##TempVar // AR1: relative Adresse #TempVar in TEMP (Kennung L)
Das Erstellen eines Pointers für die indirekte Adressierung eines Bitfeldes (*) ist also viel einfacher, wenn das Bitfeld in TEMP liegt. In Deinem Fall ist es aber tatsächlich günstiger, wenn das Eingangsbyte direkt in ein Bitfeld in der Instanz (Static) kopiert wird. Dein Code müßte also etwa so aussehen:
Code:
//#EingangsByte_Antrieb in Static Struktur #Eingang_Word kopieren
L P##Eingang_Word // relative Adresse der Struktur #Eingang_Word in dieser Instanz (Kennung DI)
TAR2 // Offset dieser Instanz (Kennung DB) im IDB
UD DW#16#FFFFFF // Bereichskennung (DB) ausblenden
+D
LAR1 // AR1: absolute Adresse der Struktur #Eingang_Word im IDB (Kennung DI)
L #EingangsByte_Antrieb
T DIW [AR1, P#0.0] // "T W [AR1, P#0.0]" geht auch
(*) Bitfeld: Ein STRUCT oder ARRAY beginnt immer an einer geraden "glatten" Word-Adresse n.0 und belegt immer ganze Vielfache von Words. Auch wenn man nur 8 Bits braucht belegt das Struct 16 Bits oder 8 Bits + 1 ungenutztes Byte.
Wenn das Bitfeld einfach 8 aufeinanderfolgend deklarierte Bools sind, dann kann man auch nur 1 Byte auf dieses Bitfeld kopieren, die Adresse des ersten Bits muß bei n.0 beginnen. Allerdings dürfen die 8 Bits dann nicht in einer STRUCT liegen, weil man kann nicht die Adresse von Struktur-Membern referenzieren, sondern nur die Anfangsadresse der Struktur selber - "P##Struct.Member" geht nicht.
Harald
Zuletzt bearbeitet: