Bit in Word setzen bzw rücksetzen

geit

Level-1
Beiträge
18
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
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
 
Hi,

Code:
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
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wilhelm möchte Bits einem Datenword setzen/rücksetzen: ;)
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). :ROFLMAO:

Code:
//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:
Code:
//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
 
Oder als Bausteine (FC..)
Code:
//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
Code:
//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
 
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)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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.

PHP:
          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]
 
Zuletzt bearbeitet:
Hi,

Wilhelm möchte Bits einem Datenword setzen/rücksetzen: ;)...
Oha wer lesen kann ist klar im Vorteil, aber es war ja auch schon spät. :ROFLMAO:

Code:
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
 

Anhänge

  • Nr_Bit_Steuern.zip
    33,6 KB · Aufrufe: 17
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


PHP:
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
 
Eine Frage hab ich jetzt immer noch wo definier ich das Word in das ich schreiben möchte???
An den Zeiger???
mfg
 
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
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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
 
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

Code:
      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. :ROFLMAO:
 
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

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.
 
Zurück
Oben