Setzen einer Boolean Var in DB

Thomas R

Level-1
Beiträge
20
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!
(Step7 5.3 SP1 /412-2DP)
Ich suche nach der besten Möglichkeit um in einem DB in einem Array[0..127] of Bool ein bestimmtes Bool zu setzen.
Die Anfangsadresse des Array im DB ist byte 664.

Wenn z.B. Format 13 in der SPS aktiv ist möchte ich Bit Nr.13 in dem Array setzen!

Mir ist es gelungen mit Hilfe eines Any-Pointers und dem BlkMov ein Byte zu schreiben.
Code:
 L     P##Temp_ANY_Pointer_in
      LAR1  
      L     B#16#10                     //Syntax ID für Step7
      T     LB [AR1,P#0.0]
      L     B#16#2                      //Wert für TYP: 1 Bool, 2 Byte, 3 Char, 4 Word, 5 Int, 6 Dword, 7 Dint, 8 Real, 9 Date, A TOD, B Time, C S5Time, E DT, 13 String
      T     LB [AR1,P#1.0]
      L     1                        //Anzahl der zu Übertragenden Daten
      T     LW [AR1,P#2.0]
      L     DBNo                      //Datenbausteinnummer
      T     LW [AR1,P#4.0]
      L     P#DBX 0.0                 //Bereichszeiger, in diesem Fall vom ersten Bit an. Für deine 2.Rezeptur brauchst du dann  P#DBX 4.0 
      L     #ByteOffset               //664
      SLW   3
      +D
      T     LD [AR1,P#6.0]

Ich habe es leider nicht geschaft mit dem Pointer anstatt eines Bytes nur ein Bit zu schreiben.

Ich habe schon versucht als Datentyp BOOL anzugeben und statt des Byteoffset direkt Bitadressiert(.xxx) zu arbeiten. Leider kann der BlkMov nicht nur ein Bit schreiben.

Kann ich irgendwie nur ein Bit setzen?

Auf #dnno
s dbx[ar1,p#0.0]
Wenn dieser Adressierung funktioniert, wie kann ich den Offset hier p#0.0 so hinbekommen das er stimmt. Für Format 9 bräuchte ich einen Offset von p#1.1. Wie kann ich diesen aus der 9 bilden?

Danke im Vorraus für alle Antworten.

Gruß
Thomas
 
Zuletzt bearbeitet:
Hallo!

Schau dir mal in der Siemenshilfe den Befehl LOOP und +AR1 an. Damit solltest du weiterkommen.
Bei schwirigkeiten kannst dich ja nochmal melden.

godi
 
Hallo

einzelne bits mit einem poiner anzuspechen ist eingentlich kein problem
du musst nur den aufbau eines pointers anschauen
die letzten 3 bits sind deine bit-Adresse
(darum kannst du einen normalen dint (oder int) mit SLD 3 auch in einen Pointer umbauen (du solltest immer D funktionen verwenden wenn du mit Pointern arbeitest))

BSP:
l l#5 --> Akku 1 = 5
sld 3 --> verschieben um 3 bit (wandeln in pointer)
t point ---> point = 5.0

l point --> point = 5.0
l #3
+d
t point --> point = 5.3

das klappt auch wenn du mehr als 7 bit dazuzählts (es wird dann automatisch auf die nächste Byteadresse erhöht) (3 bit für Bitadresse im pointer = Bit 0..7 --> wenn grössere werte addiert werden fallen die höherwertigen bits um und erhöhen die byteadresse)
den pointeraufbau findest du in der Hilfe
mit der methode erzeugst du aber nur pointer die auf keinen bestimmten datenbereich zeigen, den musst du extra angeben
das alles kannst du gut im status mitverfolgen, probiers mal aus
 
Danke für die Antwort!

Ich schaffe es ja den Pointer zu basteln. Leider gelingt es mir nicht mit
s dbx[ar1,p#0.0] oder s [ar1,p#0.0]
das Bit zu setzen.

Kann ich den Pointer of Any nur für den BlkMov verwenden?
Warum klappt das setzen des Bit so nicht?

Gruß
Thomas
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo

ich kann mir nur vorstellen das du den DB nicht geöffnet hast
wenn die adresse im ar1 stimmt sollte das eigentlich klappen
eine blkmov würde ich für bit operationen nicht verwenden
(zykluszeit und aufwand zu groß) und du brauchst eine quellstruktur die
ein gesetztes bit enthält (blkmov macht nur sinn wenn du mehr als ein
dint kopieren willst)
 

Anhänge

  • bild1.bmp
    302,2 KB · Aufrufe: 45
Danke Peter!

Die Variante die du mir vorgestellt hast funktioniert.

Eine andere Frage ist, ob der Anypointer der auf der TempVar vomTyp Any - siehe Quellcode oben - auch zu verwenden ist.

mit

Lade AnyPointer in AR1 LAR1 [L 0.0]

Setze Bit im DB dbx[AR1,p#0.0]

Gruß
Thomas
 
Hallo

nö so kalappt das nicht ganz.
Dein ANY (Temp_ANY) liegt auf den Lokalvariablen (vernutlich Eingang) und hat den Aufbau den du in der Hilfe findest. Mit dem Befehl l p##Temp_Any_pointer_in ladest du die Startadresse in den Lokalvariablen wo dein Any(aufbau) beginnt.
Darum kannst du z.B. mit dem Befehl l lb[ar1,#p2.0] auch die DB Nummer auslesen. (geht auch mit l b[ar1,#p2.0] weil die oben ja den kompletten Pointer (inc. Zielbereich) ausgelesen hast)
Du musst also nur den 6. DINT auslesen und (Startadesse des ANY) deinen offset dazurechnen und hasst diene Adresse.

Bei deinem Beispiel hast du auch den Datentye Byte statt Bit angegeben.

Wenn du mit einem Blockmove eine Variable setzten willst brauchst du eine Quelle, da der FC nur Inhalte von Anys kopiert. Soll hiessen:
Du musst ein Bit anlegen und auf 1 setzten. Das bit gibst du als Quelle an. Dein Ziel-Any ist dein zusammengebauter Any (S7-Kennung / DN-Nr. / Startadresse / Datentyp....)
Wenn do ein Bit löschen willst muss deine Quelle mit 0 gefüllt sein.
Das alles ist ziemlich aufwendig um ein Bit zu setzten, drum hab ichs noch nie probiert, sollte aber klappen.

Gruß Peter
 
Zurück
Oben