leider konnte mir Onkel Google bei meinem Problem nicht helfen - oder aber mir mangelte es an den richtigen Suchbegriffen...
Ich möchte in einem FB Bitweise auf Daten des zugehörigen Instanz DB's zugreifen. Dazu müsste ich ja den entspr DB Aufschlagen.
Da der FB aber standartmäßig in künftigen Projekten verwendet werden soll, soll eben nicht "AUF DB100" verwendet werden, sondern es soll immer der entsprechende Instanz DB aufgeschlagen werden.
Kann mir jemand sagen, wie mir das gelingen kann?
"AUF DB [#Variable]" oder gleich "AUF DB [DINO]" ist ja augenscheinlich leider nicht möglich.
Die einzige Möglichkeit einen "variablen" DB Aufzuschlagen, welche ich bis jetzt gefunden habe funktioniert nur mit MW (AUF DB [MW20]).
Da ich innerhalb des FB's aber sinnigerweise keine Merker, sondern nur IN/OUT Variablen verwenden möchte, fällt dies auch weg.
Hat jemand eine Idee oder kennt gar die Lösung für mein Problem?
Der zugehörige Instanz-DB wird zusammen mit dem FB aufgerufen. Er enthält die im FB deklarierten Variablen.
Im FB kann man dann die Variablen direkt mit Ihrem Namen verwenden.
vielen Dank für die Schnelle Antwort!
Ich habe mich - so glaube ich - nicht ganz klar ausgedrückt.
Mir geht es um folgendes:
Über eine input Variable #i_PGNO wird ein INT Wert an den FB übertragen.
Innerhalb des FB'S möchte ich jetzt auch auf einzelne Bits dieser Variable zugreifen.
Als Beispiel Mit merkern:
In MW20 steht ein Wert. Nun kann ich aber auch statt mit dem INT Wert in MW20 mit den einzelnen Bits, also bspw mit m20.2, m21.4 etc. arbeiten.
Hintergrund ist,
dass ich auf variable bitlängen des wertes prüfen und mit den Bitparitäten arbeiten muss
Ich nehme an, Du arbeitest mit AWL. Da ich meist nur mit SCL arbeite, kann ich für die 100%ige Richtigkeit nicht garantieren. In SCL weiß ich wies geht.
Aber in AWL kannst du doch mit den absoluten Adressen der Lokalvariablen arbeiten, die Du im Deklarationteil sehen kannst. Eventuell noch die Eingangsvariable vorher in eine lokale Variable kopieren.
moin..
willkommen in der "siemens" datentypenwelt.
es gibt zwei möglichkeiten in awl.
1) wie erwähnt wird bei einem normalen call aufruf die instanz mit geöffnet.
call fb1,db1
im fb kannst du dann mit zb.
L DIB 5
U DIX 4.3
direkt darauf zugreifen.
2) du kannst den DIB immer manuell öffnen. AUCH IN EINEM FC!
!!!!!ACHTUNG wenn du einen anderen Baustein als inst. öffnest, greifen auch die symbolischen stat variablen auf die addresse des geöffneten baustein zu!!!!!!
Temp. variablen bleiben unverändert.
AUF DI 10
AUF DI [Variable]
nach bearbeitung IMMER den Orginal inst wieder öffnen.
wenn du einen IN als BlockDB deklarierst, musst du ihn erst umladen (datentyp ändern) damit du ihn mit AUF nutzen kannst. ist aber auch nur ein word/int .
Ich würde das INT von den IN-Parametern in einen STRUCT mit 16 Bool Variablen im STAT Bereich kopieren und dann entsprechend bearbeiten.
Dann bleibt auch alles symbolisch und man muss nicht mit absoluten Adressen arbeiten.
Finde das unschön weil wenn sich an der Schnittstelle des FB's etwas ändert muss man die ganzen absoluten Adressen händisch wieder nachziehen.
Wenn ich z.B. das Taktbyte aus der CPU in einem FB vereinzele so deklariere ich alle Taktzeiten einzeln in einem Byte im Tempbereich. Nun im FB im ersten NW die Eingangsvariable in die Lokalvariable tranferieren und ich kann alle Taktmerker im FB einzeln verwenden obwohl ich diese als Byte in den FB übergeben habe.
Direktzugriffe auf Lokaladressen finde ich persönlich immer gefährlich. Bei Änderungen der Schnittstelle geht der Code in die Hose...
Etwas "umständlich", aber die sichere Variante:
Code:
VAR_INPUT
test : WORD ;
END_VAR
VAR_TEMP
tmpAR1 : DWORD ;
tmpAR2 : DWORD ;
wordarray : ARRAY [0 .. 15] OF BOOL ;
tmpDWORD : DWORD ;
END_VAR
BEGIN
NETWORK
TITLE =
// tmp-Variable initialisieren (DWORD wird für LAR1 benötigt)
L L#0
T #tmpDWORD
// Merkerwort von der Schnittstelle auf DWORD übertragen
L #test
T #tmpDWORD
// High-Word mit Low-Word tauschen
L #tmpDWORD
TAD
T #tmpDWORD
// tmpDWORD auf Arravariable umkopieren
TAR1 #tmpAR1 //Adressregister retten
TAR2 #tmpAR2
LAR1 P##tmpDWORD //"Quelle"
LAR2 P##wordarray //"Ziel"
L W [AR1,P#0.0] //tmpDWORD auf wordarray schreiben (Highbyte mit Lowbyte tauschen)
TAW
T W [AR2,P#0.0]
LAR1 #tmpAR1 //Adressregister zurückschreiben
LAR2 #tmpAR2
Nun kannst Du mit den Arrayvariablen arbeiten. Z.B. MW20 wird an die Schnittstelle geschaltet. M20.3 -> wordarray[3]
ich würde das einfach mit indirekter Adressierung lösen.
Einfach so in die Lokaldaten schreiben wie Pinky ohne Variablen finde ich nicht schön.
Code:
// über indirekte Adressierung
LAR1 P##input
U [AR1,P#0.0]
= #out1
U [AR1,P#0.1]
= #out2
// über indirekte Adressierung mit Zwischenspeicher in Array
LAR1 P##tempB
L #input
T B [AR1,P#0.0]
U #tempB[2]
= #out3
U #tempB[3]
= #out4