# Bit in Word setzen bzw rücksetzen



## geit (24 Oktober 2010)

Hallo
ich arbeite grade an meiner Facharbeit für meinen Techniker abschluss.
Nun habe ich folgendes Problem.
Ich habe mir Palettenfunktionen gebaut und in einem Datenword jedes Bit einem Pallettenplatz zugewiesen.
Nun möchte ich die Bits einzeln setzen bzw rücksetzen.
Ich habe einen Zähler der mir sagt das wievielte Bit gesetzt bzw zurück gesetzt werden muss.

Hat jemand eine Idee wie ich das realisieren kann???

mfg
Wilhelm


----------



## dalbi (24 Oktober 2010)

Hi,


```
FUNCTION FC 103 : VOID
TITLE =
//Diese Funktion steuert in abhängigkeit der Nummer (Nr),
//ein Bit im Any-Pointer (Bitfeld).
//Der Zustand der aktuellen Bit-Nummer wird im Status (Status) 
//angezeigt.
//- Zulässige Parameter für den Any-Pointer sind:
//    BIT, BYTE, WORD u. DWORD
//- Folgende Fehler (Fehler) werden ausgewertet: 
//    Parametrierung, Nr größer Bitanzahl u. Nr kleiner 0
//    Fehler wird im BIE-Bit signalisiert.
//    Parametrierung Fehlerfrei BIE = TRUE
//     "     "    "  Fehler     BIE = FALSE
AUTHOR : dalbi
FAMILY : SIGNAL
NAME : NRBIT
VERSION : 1.1


VAR_IN_OUT
  NR : INT ;    //Nummer
  ZEIGER : ANY ;    //Zeiger Bitfeld
END_VAR
VAR_TEMP
  tLaenge : INT ;    //Länge in Bits
  tZaehler : INT ;    //Schleifenzähler
  tDBNr : WORD ;    //Datenbausteinnummer
  tTyp : BYTE ;    //Datentyp
  SaveAR1 : DINT ;    //Speicher Adressregister 1
  SaveAR2 : DINT ;    //Speicher Adressregister 2
END_VAR
BEGIN
NETWORK
TITLE =Adressregister sichern

      TAR1  #SaveAR1; 
      TAR2  #SaveAR2; 

NETWORK
TITLE =Any-Pointer zerlegen

      L     P##ZEIGER; // AR1 auf ANY
      LAR1  ; 

      L     W [AR1,P#4.0]; // DB-Nummer
      T     #tDBNr; 

      L     W [AR1,P#2.0]; // Wiederholfaktor für Typ
      T     #tLaenge; 

      L     B [AR1,P#1.0]; // Datentyp
      L     B#16#1; // BIT
      ==I   ; 
      L     0; 
      SPB   set1; 

      L     B [AR1,P#1.0]; // Datentyp
      L     B#16#2; // BYTE
      ==I   ; 
      L     1; 
      SPB   set1; 

      L     B [AR1,P#1.0]; // Datentyp
      L     B#16#4; // WORD
      ==I   ; 
      L     2; 
      SPB   set1; 

      L     B [AR1,P#1.0]; // Datentyp
      L     B#16#6; // DWORD
      ==I   ; 
      L     3; 
      SPB   set1; 
      BEA   ; // Bausteinende wenn Typ nicht past
set1: T     #tTyp; 

NETWORK
TITLE =Bitbereich löschen

      L     D [AR1,P#6.0]; // AR1 auf Anfangsadresse
      LAR1  ; 

      AUF   DB [#tDBNr]; // DB aufschlagen

      L     #tLaenge; 
next: T     #tZaehler; 

      L     #tTyp; 
      SPL   nix; 
      SPA   BIT; // Sprung bei 0
      SPA   BYTE; // Sprung bei 1
      SPA   WORD; // Sprung bei 2
      SPA   DW; // Sprung bei 3
nix:  L     0; 
      T     #tTyp; 
      BEA   ; 
BIT:  SET   ; 
      R      [AR1,P#0.0]; 
      +AR1  P#0.1; // Weiter auf nächstes Bit
      SPA   cr; 
BYTE: L     B#16#0; 
      T     B [AR1,P#0.0]; 
      +AR1  P#1.0; // Weiter auf nächstes Byte
      SPA   cr; 
WORD: L     0; 
      T     W [AR1,P#0.0]; 
      +AR1  P#2.0; // Weiter auf nächstes Word
      SPA   cr; 
DW:   L     L#0; 
      T     D [AR1,P#0.0]; 
      +AR1  P#4.0; // Weiter auf nächstes DW
cr:   L     #tZaehler; 
      LOOP  next; 

      LAR1  #SaveAR1; // Adressregister 1 rückschreiben
      LAR2  #SaveAR2; // Adressregister 2 rückschreiben

NETWORK
TITLE =Any-Pointer zerlegen

      L     P##ZEIGER; // AR1 auf Bitfeld
      LAR1  ; 

      L     B [AR1,P#1.0]; // Datentyp
      L     B#16#1; // BIT
      ==I   ; 
      SPB   bit; 

      TAK   ; 
      L     B#16#2; // BYTE
      ==I   ; 
      SPB   byte; 

      TAK   ; 
      L     B#16#4; // WORD
      ==I   ; 
      SPB   word; 

      TAK   ; 
      L     B#16#6; // DWORD
      ==I   ; 
      SPB   dw; 

      SPA   err; // Fehler, wenn kein Typ

bit:  L     1; // BIT
      SPA   set; 
byte: L     8; // BYTE
      SPA   set; 
word: L     16; // WORD
      SPA   set; 
dw:   L     32; // DWORD
set:  L     W [AR1,P#2.0]; // Wiederholfaktor für Typ
      *I    ; 
      T     #tLaenge; // Länge in Bit

      L     #NR; 
      L     1; 
      >=I   ; 
      SPB   m031; 
      T     #NR; 
m031: L     #NR; 
      L     #tLaenge; // Wiederholfaktor für Typ
      <=I   ; 
      SPB   m032; 
      T     #NR; 
m032: NOP   0; 

      L     W [AR1,P#4.0]; // DB-Nummer
      T     #tDBNr; 

      AUF   DB [#tDBNr]; // DB aufschlagen

      L     #NR; 
      L     P#0.1; 
      *D    ; 
      L     P#0.1; 
      -D    ; 
      L     D [AR1,P#6.0]; // AR1 auf Anfangsadresse
      +D    ; 
      LAR1  ; 

NETWORK
TITLE =Logik

      SET   ; 
      =      [AR1,P#0.0]; // steuern

NETWORK
TITLE =Auswertung BIE-Bit

      SET   ; // IO
      SPA   io; // BIE-Bit auf 1 setzen
err:  SET   ; // Bei Fehler
      CLR   ; // BIE-Bit auf 0 setzen
io:   SAVE  ; // BIE-Bit sichern

      LAR1  #SaveAR1; // Adressregister 1 rückschreiben
      LAR2  #SaveAR2; // Adressregister 2 rückschreiben

END_FUNCTION
```

Gruss Daniel


----------



## geit (24 Oktober 2010)

Hallo
ich hab mir den mal in S7 eingehackt......

So ganz versteh ich das nicht.....
Wie kann ich ein Word definieren? in dem ich Bits setzen bzw rücksetzen will....
Und wie kann ich die Bits dann setzen bzw rücksetzen???

mfg
wilhelm


----------



## dalbi (24 Oktober 2010)

Hi,

anbei noch ein kleines Beispiel.

Gruss Daniel


----------



## dalbi (24 Oktober 2010)

geit schrieb:


> ...Und wie kann ich die Bits dann setzen bzw rücksetzen???



Das entsprechende Bit wird durch die Nummer gesetzt.

z.B. Nummer = 1 entspricht im Beispiel M2.0, Nummer = 2 wäre M2.1 und Nummer = 16 Bit M3.7 im MW2.

Gruss Daniel


----------



## PN/DP (24 Oktober 2010)

Wilhelm möchte Bits einem Daten*word* setzen/rücksetzen: 


geit schrieb:


> Ich habe mir Palettenfunktionen gebaut und in einem Datenword jedes Bit einem Pallettenplatz zugewiesen.
> Nun möchte ich die Bits einzeln setzen bzw rücksetzen.



Andere Variante:
Der Simatic Manager enthält eine Funktion FC97 "DECO" - Vorgegebenes Bit im DWord setzen
Bibliotheken > Standard Library > TI-S7 Converting Blocks > FC97 DECO
Die Baustein-Hilfe ist allerdings teilweise falsch (mit der Beschreibung des FC96 vertauscht). 


```
//Bitmuster mit Bit[Bitnummer]=1 erzeugen
      CALL  FC97
       IN     :=MW100                   //Bitnummer 0..31 (für Word: 0..15)
       RET_VAL:=#temp_dwBitmuster       //Bitmuster mit Bit[Bitnummer]=1

//Beispiel Bit in DWord setzen
      L     #temp_dwBitmuster
      L     DB1.DBD0
      OD
      T     DB1.DBD0

//Beispiel Bit in DWord rücksetzen
      L     #temp_dwBitmuster
      INVD
      L     DB1.DBD0
      UD
      T     DB1.DBD0

//Beispiel Bit in Word setzen
      L     #temp_dwBitmuster
      L     DB1.DBW0
      OW
      T     DB1.DBW0

//Beispiel Bit in Word rücksetzen
      L     #temp_dwBitmuster
      INVI
      L     DB1.DBW0
      UW
      T     DB1.DBW0
```

Alternativ zum FC97 tuts auch diese Befehlsfolge:

```
//alternativ Bitmuster mit Bit[Bitnummer]=1 erzeugen
      L     MW100                       //Bitnummer 0..31 (für Word: 0..15)
      L     1
      SLD
      T     #temp_dwBitmuster           //Bitmuster mit Bit[Bitnummer]=1
```

Harald


----------



## PN/DP (24 Oktober 2010)

Oder als Bausteine (FC..)

```
//Bit in einem Word setzen
VAR_IN
  Nr : INT     //Bitnummer 0..15 - wird nicht geprüft!
END_VAR
VAR_IN_OUT
  Datenword : WORD
END_VAR

      L     #Nr                         //Bitnummer 0..15
      L     1
      SLD
      L     #Datenword
      OW
      T     #Datenword
```


```
//Bit in einem Word rücksetzen
VAR_IN
  Nr : INT     //Bitnummer 0..15 - wird nicht geprüft!
END_VAR
VAR_IN_OUT
  Datenword : WORD
END_VAR

      L     #Nr                         //Bitnummer 0..15
      L     1
      SLD
      INVI
      L     #Datenword
      UW
      T     #Datenword
```

Harald


----------



## peter(R) (24 Oktober 2010)

Wenn zB. Das Datenwort 0 im DB 1 gemeint sei, dann
besteht dieses Datenwort aus den "Datenbits"  Db1.DBX0.0 bis DB1.DBX1.7

Diese wiederum können einfach mit zB.

M1.1
= Db1.dbx0.6

oder 

U m125.3
S DB1.dbx1.4

also wie zB. jeder Merker bearbeitet und auch natürlich abgefragt werden.

u DB1.DBX 0.2
= M11.7


peter(R)


----------



## geit (24 Oktober 2010)

moin
@ peter das wird wohl meine Lösung sein.
Schieben kommt nicht in Frage weil alle anderen Bits in dem Word an der alten stelle erhalten bleiben müssen. 
Das Word wird dazu genutzt die nächste frei Pallette ausfindig zu machen.
Hier ein kurzer auszug aus der Erkennung.
und wenn die Pallette dann belegt wurde wollte ich mit einer eleganten lösung das bit für z.B.  #Pal_1 in dem Datenword setzen und bei entnahme rücksetzen.


```
U     #Pal_1                      // wenn Pallette 1 frei dann automatische anwahl
        SPB   pa1                         // wenn Pallette belegt dann springe zur nächsten
        L     1                           // Lade Soll Palletten Nr
        T     #erste_freie_Pal
        SPA   end
  pa1:  NOP   0
        U     #Pal_2
        SPB   pa2                         // wenn Pallette 2 frei dann automatische anwahl
        L     2
        T     #erste_freie_Pal
        SPA   end
  pa2:  NOP   0
        U     #Pal_3
        SPB   pa3
        L     3                           // wenn Pallette 3 frei dann automatische anwahl
        T     #erste_freie_Pal
        SPA   end
  pa3:  NOP   0
```
[FONT=&quot]
[/FONT]


----------



## dalbi (24 Oktober 2010)

Hi,



PN/DP schrieb:


> Wilhelm möchte Bits einem Daten*word* setzen/rücksetzen: ...


Oha wer lesen kann ist klar im Vorteil, aber es war ja auch schon spät. 


```
FUNCTION FC 103 : VOID
TITLE =
//Diese Funktion steuert in abhängigkeit der Nummer (Nr)
//ein Bit im Any-Pointer (Bitfeld).
AUTHOR : dalbi
VERSION : 1.0


VAR_INPUT
  Steuern : BOOL ;    //Ein / Aus
  NR : INT ;    //Nummer
END_VAR
VAR_IN_OUT
  ZEIGER : ANY ;    //Zeiger Bitfeld
END_VAR
VAR_TEMP
  tSaveAR1 : DWORD ;    //Speicher Adressregister 1
  tSaveAR2 : DWORD ;    //Speicher Adressregister 2
  tDBNr : WORD ;    //Datenbausteinnummer
END_VAR
BEGIN
NETWORK
TITLE = 

      TAR1  #tSaveAR1; // Adressregister sichern
      TAR2  #tSaveAR2; 

      L     P##ZEIGER; // AR1 auf Bitfeld
      LAR1  ; 

      L     W [AR1,P#4.0]; // DB-Nummer
      T     #tDBNr; 

      AUF   DB [#tDBNr]; // DB aufschlagen

      L     #NR; 
      L     P#0.1; 
      *D    ; 
      L     P#0.1; 
      -D    ; 
      L     D [AR1,P#6.0]; // AR1 auf Anfangsadresse
      +D    ; 
      LAR1  ; 

      U     #Steuern; 
      =      [AR1,P#0.0]; // steuern

      LAR1  #tSaveAR1; // Adressregister 1 rückschreiben
      LAR2  #tSaveAR2; // Adressregister 2 rückschreiben

END_FUNCTION
```

Gruss Daniel


----------



## geit (24 Oktober 2010)

So ich hab da mal eine kleine Änderung vorgenommen.
Wenn ich z. B. Bit 6 setzen bzw rücksetzen will, dann möchte ich das über 2 Eingänge machen. 
Funktioniert das so wie ich das geändert habe???
mfg
Wilhelm



```
FUNCTION FC 103 : VOID
TITLE =
//Diese Funktion steuert in abhängigkeit der Nummer (Nr)
//ein Bit im Any-Pointer (Bitfeld).
AUTHOR : dalbi
VERSION : 1.0


VAR_INPUT
Setzen : Bool // Bit setzen
Rücksetzen: Bool // Bit zurücksetzen
   NR : INT ;    //Nummer
END_VAR
VAR_IN_OUT
  ZEIGER : ANY ;    //Zeiger Bitfeld
END_VAR
VAR_TEMP
  tSaveAR1 : DWORD ;    //Speicher Adressregister 1
  tSaveAR2 : DWORD ;    //Speicher Adressregister 2
  tDBNr : WORD ;    //Datenbausteinnummer
END_VAR
BEGIN
NETWORK
TITLE = 

      TAR1  #tSaveAR1; // Adressregister sichern
      TAR2  #tSaveAR2; 

      L     P##ZEIGER; // AR1 auf Bitfeld
      LAR1  ; 

      L     W [AR1,P#4.0]; // DB-Nummer
      T     #tDBNr; 

      AUF   DB [#tDBNr]; // DB aufschlagen

      L     #NR; 
      L     P#0.1; 
      *D    ; 
      L     P#0.1; 
      -D    ; 
      L     D [AR1,P#6.0]; // AR1 auf Anfangsadresse
      +D    ; 
      LAR1  ; 

      U     #Setzen; 
      UN    #Rücksetzen
      S      [AR1,P#0.0]; // Bit setzen

      U     #Rücksetzen; 
      UN    #Setzen; 
      R      [AR1,P#0.0]; // Bit zurücksetzen


      LAR1  #tSaveAR1; // Adressregister 1 rückschreiben
      LAR2  #tSaveAR2; // Adressregister 2 rückschreiben

END_FUNCTION
```


----------



## dalbi (24 Oktober 2010)

Hi,

ja. 

Gruss Daniel


----------



## geit (24 Oktober 2010)

Eine Frage hab ich jetzt immer noch wo definier ich das Word in das ich schreiben möchte???
An den Zeiger???
mfg


----------



## dalbi (24 Oktober 2010)

Genau an den Zeiger schreibst Du z.B. P#M100.0 BYTE 2 für MW100 oder P#DB1.DBX 0.0 BYTE 2 für DB1.DBW0 bei Doppelworten BYTE 4.

Gruss Daniel


----------



## geit (24 Oktober 2010)

Jetzt sagt siemens das das speichern nicht möglich ist da sich in dem Netzwerk noch ungülige anweisungen befinden.
Bei den beiden zeilen.....
Hast du dafür auch noch eine Idee??


 L     P##ZEIGER      // AR1 auf Bitfeld
LAR1


----------



## dalbi (24 Oktober 2010)

Was hast Du gemacht? In dem Beitrag http://sps-forum.de/showpost.php?p=288468&postcount=10 hatte ich doch den Baustein als S7 Projekt hochgeladen, einfach mit dem Simatic-Manager dearchivieren und fertig. Das andere ist eine AWL-Quelle die kann man unter Quellen importieren.

Gruss Daniel


----------



## geit (24 Oktober 2010)

So jetzt hab ich den Baustein zum laufen. 
Das Problem ist aber immer wenn ich ein neues Bit setze geht das zuvor gesetzte bit verloren. Also wird wieder auf 0 gesetzt.

Soll das so sein???
mfg
wilhelm


----------



## dalbi (24 Oktober 2010)

Hi,

nein in dem Baustein wird in Abhängigkeit von dem Steuern das Bit mit der (Nr) beschrieben. Wie hast Du das jetzt beschalten?

Gruss Daniel


----------



## Ralle (24 Oktober 2010)

@Dalbi


```
L     #NR; 
     [COLOR=Red] L     P#0.1; 
      *D    ; 
      L     P#0.1; 
      -D    ; [/COLOR]
      L     D [AR1,P#6.0]; // AR1 auf Anfangsadresse
      +D    ; 
      LAR1  ;
```

Den Sinn der rot markierten Befehle erklärst du uns sicher auch noch.


----------



## Ralle (24 Oktober 2010)

geit schrieb:


> So jetzt hab ich den Baustein zum laufen.
> Das Problem ist aber immer wenn ich ein neues Bit setze geht das zuvor gesetzte bit verloren. Also wird wieder auf 0 gesetzt.
> 
> Soll das so sein???
> ...



Du mußt die Nummer ändern, bevor du "Steuern" änderst (ist für deinen Fall eher unpraktisch), der Baustein kann an dieser Stelle für deine Zwecke sicherlich noch ein wenig bedienfreundlicher gestaltet werden, aber die Funktion ist ja schon mal da.


----------



## dalbi (24 Oktober 2010)

Ralle schrieb:


> @Dalbi
> 
> 
> ```
> ...



Klar, das es bei 1 los geht.  1 = Bit 0.0

Gruss Daniel


----------



## geit (24 Oktober 2010)

Also fehler gefunden.... der Baustein funktioniert jetzt wie er soll....
Danke noch mal!!!!!!!!!!!!!!!!


----------



## Ralle (24 Oktober 2010)

dalbi schrieb:


> Klar, das es bei 1 los geht.  1 = Bit 0.0
> 
> Gruss Daniel



Ähm ok, akzeptiert, aber wozu 


```
L     P#0.1; 
      *D    ;
```
Was also soll das eigentlich genau bewirken?

Achtung noch, bei Angabe von 0 und Werten >= 17 werden "benachbarte" Bits übrigens gesetzt/rückgesetzt. Z.bsp. MW10 per Zeiger adressiert, dann wird MW8 bzw. MW12 usw. manipuliert. Von daher macht es Sinn die Werte von Nummer auf 1-16 zu begrenzen.


----------



## dalbi (24 Oktober 2010)

Hi,

oh stimmt. 


```
L     #NR; 
[COLOR=Black]      L     P#0.1; 
      -D    ; 
[/COLOR]      L     D [AR1,P#6.0]; // AR1 auf Anfangsadresse
      +D    ; 
      LAR1  ;
```

so würde es auf das selbe heraus kommen.

Gruss Daniel


----------



## Ralle (24 Oktober 2010)

dalbi schrieb:


> Hi,
> 
> oh stimmt.
> 
> ...



Und ich dachte schon, du willst uns wieder mal mit Trick17 überraschen.  Aber das ist ja nicht weiter schlimm, die Multiplikation beeinflußt das Ergebnis ja nicht.


----------



## dalbi (24 Oktober 2010)

Hi,

zu meiner Verteidigung hab ich das ganze mal noch ein wenig angepasst. 
Die Länge des angegebenen ANYs wird überprüft und begrenzt. Signalisierung erfolgt über das BIE-Bit (ENO).


```
FUNCTION FC 103 : VOID
TITLE = 
//Diese Funktion steuert in abhängigkeit der Eingänge "S" (setzen) und "R" 
//(rücksetzen) ein Bit (Nr) im Any-Pointer (Bitfeld).
//
//- Zulässige Parameter für den Any-Pointer sind:
//    BIT, BYTE, WORD u. DWORD
//- Folgende Fehler (Fehler) werden ausgewertet: 
//    Parametrierung, Nr größer Bitanzahl u. Nr kleiner 0
//    Fehler wird im BIE-Bit signalisiert.
//    Parametrierung Fehlerfrei BIE = TRUE
//     "     "    "  Fehler     BIE = FALSE
AUTHOR : dalbi
VERSION : 1.0


VAR_INPUT
  S : BOOL ;    //Bit setzen
  R : BOOL ;    //Bit rücksetzen
  NR : INT ;    //Nummer
END_VAR
VAR_IN_OUT
  ZEIGER : ANY ;    //Zeiger Bitfeld
END_VAR
VAR_TEMP
  tSaveAR1 : DWORD ;    //Speicher Adressregister 1
  tSaveAR2 : DWORD ;    //Speicher Adressregister 2
  tDBNr : WORD ;    //Datenbausteinnummer
  tLaenge : INT ;    
END_VAR
BEGIN
NETWORK
TITLE =Prüfen

      TAR1  #tSaveAR1; // Adressregister sichern
      TAR2  #tSaveAR2; 

      L     P##ZEIGER; // AR1 auf Bitfeld
      LAR1  ; 

      L     W [AR1,P#4.0]; // DB-Nummer
      T     #tDBNr; 

      L     B [AR1,P#1.0]; // Datentyp
      L     B#16#1; // BIT
      ==I   ; 
      SPB   bit; 

      TAK   ; 
      L     B#16#2; // BYTE
      ==I   ; 
      SPB   byte; 

      TAK   ; 
      L     B#16#4; // WORD
      ==I   ; 
      SPB   word; 

      TAK   ; 
      L     B#16#6; // DWORD
      ==I   ; 
      SPB   dw; 

      SPA   err; // Fehler, wenn kein Typ

bit:  L     1; // BIT
      SPA   set; 
byte: L     8; // BYTE
      SPA   set; 
word: L     16; // WORD
      SPA   set; 
dw:   L     32; // DWORD
set:  L     W [AR1,P#2.0]; // Wiederholfaktor für Typ
      *I    ; 
      T     #tLaenge; // Länge in Bit

      L     #NR; 
      L     1; 
      <I    ; 
      SPB   err; 

      L     #NR; 
      L     #tLaenge; // Wiederholfaktor für Typ
      >I    ; 
      SPB   err; 

NETWORK
TITLE = 

      AUF   DB [#tDBNr]; // DB aufschlagen

      L     #NR; 
      L     P#0.1; 
      -D    ; 
      L     D [AR1,P#6.0]; // AR1 auf Anfangsadresse
      +D    ; 
      LAR1  ; 

NETWORK
TITLE =Logik

      U     #S; 
      S      [AR1,P#0.0]; 
      U     #R; 
      R      [AR1,P#0.0]; 

NETWORK
TITLE =Auswertung BIE-Bit

      SET   ; // IO
      SPA   io; // BIE-Bit auf 1 setzen
err:  NOP   0; // Bei Fehler
      CLR   ; // BIE-Bit auf 0 setzen
io:   SAVE  ; // BIE-Bit sichern

      LAR1  #tSaveAR1; // Adressregister 1 rückschreiben
      LAR2  #tSaveAR2; // Adressregister 2 rückschreiben

END_FUNCTION
```

Gruss Daniel


----------



## PN/DP (25 Oktober 2010)

geit schrieb:


> Schieben kommt nicht in Frage weil alle anderen Bits in dem Word an der alten stelle erhalten bleiben müssen.


Wie kommst Du auf Schieben? Kein Programmbeispiel in diesem Thread schiebt Dein Datenword.



geit schrieb:


> und wenn die Pallette dann belegt wurde wollte ich mit einer eleganten lösung das bit für z.B. #Pal_1 in dem Datenword setzen und bei entnahme rücksetzen.


Also für elegante Lösungen ist die Grundvoraussetzung, daß man zuerst mal versteht, was man überhaupt tut.
Ein Monsterbaustein mit vielen P# und ARx und unangemessenem Ressourcenverbrauch sieht zwar für Laien 
hinreichend kompliziert aus, ist aber von Eleganz ganz weit weg.

Und noch ein Tip - 
kläre und prüfe für Dich folgende Fragen, bevor in einer späteren Visualisierung das große Erwachen kommt:
Wie nummerierst Du die Bits in Deinem Datenword? Von 0 bis 15 oder von 1 bis 16?
Welches Bit ist Deinem Willen nach das erste (niedrigste?) Bit in Deinem Datenword?

Harald


----------



## Tigerente1974 (6 März 2013)

Ich grab den thread noch einmal aus, weil ich aktuell die gleiche Problemstellung lösen will.

Für Störmeldungen am HMI sollen Bits in einem WORD gesetzt werden. Das niedrigste Bit soll bei 1, das höchste Bit bei 16 gesetzt werden. Das Störmeldewort soll dabei nicht mit 0 initialisiert werden, da ich ggf. nacheinander mehrere Bits gesetzt werden sollen. Es soll also durch eine INT-Variable bestimmt werden, welche Bitposition gesetzt wird. Ich habe das jetzt wie folgt gelöst. Die Lösung funktioniert in PLCSIM. Da ich aber nicht so oft mit Pointern hantiere, würde mich interessieren, ob da irgendeine "Krücke" verbaut ist:


```
// Störmeldewort rangieren
      L     #Stoermeldewort
[COLOR=#ff0000]  //     TAW   [/COLOR]
      T     #Meldewort
      LAR1  P##Meldewort

// Grenzen prüfen (1..16)
      U(    
      L     #Stoerungsnummer
      L     0
      >I    
      )     
      U(    
      L     #Stoerungsnummer
      L     16
      <=I   
      )     
      SPBN  ende

// Initialisieren. (Schleife beginnt bei 1)
      L     1
      T     #Nummer

// Wenn Schleifenzähler = Störungsnummer -> Bit setzen
m001: L     #Nummer
      L     #Stoerungsnummer
      ==I   
      SPB   m002

// Schleifenzähler + AR1 incrementieren (bis 16)
      L     #Nummer
      INC   1
      T     #Nummer
      L     P#0.1
      +AR1  

      L     #Nummer
      L     16
      <I    
      SPB   m001

// Bit gemäß AR1 setzen + zurückrangieren
m002: SET   
      S     L [AR1,P#0.0]
      L     #Meldewort
[COLOR=#ff0000]  //    TAW   [/COLOR]
      T     #Stoermeldewort

ende: NOP   0
```

Edit: Gerade noch gesehen. Das TAW war falsch.


----------

