# Aus 200Byte je 1Bit auslesen diese nacheinander abspeichern aber mit verdrehten Bytes



## godi (15 Januar 2008)

Hallo!

Ich will aus 200Bytes jeweils das Bit x.1 auslesen und diese Bits hintereinander speichern wobei ich aber dann in jedem Word das low und high Byte vertauschen muss.

Also das mit dem auslesen ist ja kein Problem und die Bits hintereinander abspeichern. Aber wenn ich die ersten 16Bit übertragen habe dann muss ich die Bytes drehen!
Ich weiß nicht wie ich das machen soll ohne das ich die Werte zwischenspeichere.


Hier mal ein auszug aus dem Code:


```
L     #Anzahl_Stoermeldungen
Lo1:  T     #LOOP_Stoerungen_an_HMI

      U     DBX [AR1,P#0.1]     //Lese Bits aus Byte
      =     DIX [AR2,P#0.0]     //Schreibe Bits hintereinander

      TAR2                          //Probiere irgendwie von den gespeicherten Bits bei jedem Word das LOW und HIGH Byte zu drehen
      L     P#2.0
      MOD   
      L     0
      ==I   
      SPBN  Lo11
      L     DBW [AR2,P#0.0]
      TAW   
      T     DBW [AR2,P#0.0]

Lo11: L     P#0.0
      +AR1  P#2.0
      +AR2  P#0.1

      L     #LOOP_Stoerungen_an_HMI
      LOOP  Lo1
```

Würde das mit SCL einfacher sein?

godi


----------



## marlob (15 Januar 2008)

```
L     MW10    //Lade den Wert von MW10 in AKKU 1.
TAW            //Kehre die Reihenfolge der Bytes in AKKU1-L um.
T     MW20    //Transferiere das Ergebnis nach MW20.
```
wofür brauchst du das?
Aber den Befehl TAW hast du ja schon selber gefunfen


----------



## godi (15 Januar 2008)

Ich habe in einem Datenbaustein in jedem Word das Bit 0.1 als Störmeldung das ich in einem DB schreiben will zur Übergabe an WinCC flexible.
Naja und da muss ich eben die Bytes drehen damit die Störungen in flex nicht verdreht sind.


----------



## marlob (15 Januar 2008)

godi schrieb:


> Ich habe in einem Datenbaustein in jedem Word das Bit 0.1 als Störmeldung das ich in einem DB schreiben will zur Übergabe an WinCC flexible.
> Naja und da muss ich eben die Bytes drehen damit die Störungen in flex nicht verdreht sind.


Pass doch deine Meldetexte in WinCC flex an


----------



## godi (15 Januar 2008)

Wollte da mal was Probieren:
Für eine Störmeldung einen UDT anlegen wo ich ca5Bits drinnen habe.
Diesen UDT kann ich dann einfach an die Motorbausteine usw. übergeben.
In einen Motorbaustein kann ich dann die Störung generieren und das Störbit in den UDT schreiben. Desweiteren kann ich dann aus dem UDT herauslesen ob die Störmeldung in der HMI schon gelesen worden ist usw.
Und in einem Störungsbaustein bereite ich dann die ganzen Bits für die HMI vor.


----------



## Larry Laffer (15 Januar 2008)

Hallo Godi,
da du ja weiter oben im Thrwead danach fragtest habe ich dir mal meinen Störungs-FB in SCL hier eingestellt.

```
FUNCTION_BLOCK FB16                  // UP Auswertung Störungen
TITLE   = 'UP Auswertung Störungen'  // UP Auswertung Störungen
AUTHOR  : 'L.L.'
VERSION : '1.2'   //   22.08.07
//KNOW_HOW_PROTECT
// -----------------------------------------------------------------------------------------------------------------------
//     Bausteinparameter 
// -----------------------------------------------------------------------------------------------------------------------
VAR_INPUT
    DT_Quit  : BOOL ;   // DT Quittierung Störung
    DT_Start : BOOL ;   // DT Start Anlage
    M_Blink  : BOOL ;   // M Blink-Takt für LM_Stoerung 
END_VAR
VAR_IN_OUT
END_VAR
VAR_OUTPUT
    LM_Stoerung : BOOL ;   // LM Stoerung vorhanden
END_VAR
VAR
   Stoerung_Quit      : BOOL ;   // ext. Quittierung Störung
   Meldung_vorhanden  : BOOL ;   // Meldung vorhanden
   Stoerung_vorhanden : BOOL ;   // Stoerung vorhanden
   
   Meldung  : ARRAY [001 .. 016] OF BOOL ;    // Bereich Info-Meldungen 
      w_Meldung  AT Meldung  : WORD ;
   Stoerung : ARRAY [017 .. 256] OF BOOL ;    // Bereich Stör-Meldungen
      w_Stoerung AT Stoerung : ARRAY [2 .. 16] OF WORD ;
                                               
   OP_Stoermeldungen : ARRAY [1..16] OF WORD ; // Störmelde-Bereich für OP                                            
END_VAR
VAR_TEMP
   i    : INT ;     // Schleifen-Variable
END_VAR

// -----------------------------------------------------------------------------------------------------------------------
BEGIN
// -----------------------------------------------------------------------------------------------------------------------
IF DT_Quit OR DT_Start OR Stoerung_Quit THEN
   FOR i := 2 TO 16 BY 1 DO
      w_Stoerung[i] := 0 ;
   END_FOR ;
END_IF ;
Meldung_vorhanden  := false ;
Stoerung_vorhanden := false ;
OP_Stoermeldungen[1] := ROL (IN:=w_Meldung , n:=8) ;
IF w_Meldung <> 0 THEN Meldung_vorhanden := true ; END_IF ;
FOR i := 2 TO 16 BY 1 DO
   OP_Stoermeldungen[i] := ROL (IN:=w_Stoerung[i] , n:=8) ;   
   IF w_Stoerung[i] <> 0 THEN Stoerung_vorhanden := true ; END_IF ;
END_FOR ;
LM_Stoerung := Stoerung_vorhanden AND M_Blink ;

// -----------------------------------------------------------------------------------------------------------------------
END_FUNCTION_BLOCK
```
 
Bei meinem Baustein geht es mir nur darum, zu wissen ob irgendeine Störung anliegt, alle auf einmal quittieren zu können und sie einmal DB-richtig entgegenzunehmen und OP-richtig dem OP (oder TP oder PC) zur Verfügung zu stellen.
Vielleicht kannst du damit ja was machen oder es als Anregung gebrauchen ...

Gruß
LL


----------



## godi (15 Januar 2008)

@L.L.

Wie überträgst du dann die Daten in deine HMI?
Direkt aus dem Instanzdatenbaustein?

godi


----------



## Larry Laffer (16 Januar 2008)

Hallo Godi,
der Bereich OP_Störmeldungen ist der Bereich auf den die Visu zugreift und der ist dort auch projektiert. Der FB16 dient nur der Auswertung der Einzelbits und dem Umschaufeln. Hintergrund bei mir (wie scheinbar auch bei dir) war: ich wollte. dass Störungsbit 17 auch Störmeldung 17 ansteuert - das hatte mich immer genervt ...

Wie du aus anderen Beiträgen von mir vielleicht schon herausgelesen hast, ist bei mir ein I-DB kein Heiligtum, sondern für mich ist das ein ganz normaler DB, wie andere auch. Was man damit macht und was nicht und ob das klappt oder nicht hat natürlich immer etwas mit Disziplin zu tun.

Vielleicht kannst du das ja gebrauchen ...

Gruß
LL


----------



## Fabix (12 Februar 2008)

*unwissenheit*

Hallo habe ein ähnliches Problemchen und wollte mir den Code anpassen. Leider bin ich noch am Anfang meines selbststudium und komm da noch nicht ganz mit. 

Mein Problem: 
Ich habe in einem DB einen Bereich bei dem ich jedes gerade bit .7 auslesen möchte und in ein dw schreiben möchte. 

Nachfolgenden Code habe ich einfach mal übernommen. 
anzahl_Störmeldungen als Variable IN (Int-Format) deklariert
loop als tempvariable (INT-Format)
AR1 und AR2 als In-Out (Pointer)

Mein Problem ist nun, das sich bei mir einfach mal nichts tut :-(
Wobei ich dazu sagen muss, dass ich keine ahnung von pointer und co habe. 

Falls mir da jemand einen kleinen hinweis geben kann wäre ich sehr dankbar


Gruß fabix

    L     #Anzahl_Stoermeldungen
Lo1:  T     #LOOP_Stoerungen_an_HMI

      U     DBX [AR1,P#0.1]     //Lese Bits aus Byte
      =     DIX [AR2,P#0.0]     //Schreibe Bits hintereinander

      TAR2                          //Probiere irgendwie von den gespeicherten Bits bei jedem Word das LOW und HIGH Byte zu drehen
      L     P#2.0
      MOD   
      L     0
      ==I   
      SPBN  Lo11
      L     DBW [AR2,P#0.0]
      TAW   
      T     DBW [AR2,P#0.0]

Lo11: L     P#0.0
      +AR1  P#2.0
      +AR2  P#0.1

      L     #LOOP_Stoerungen_an_HMI
      LOOP  Lo1


----------



## volker (12 Februar 2008)

in der *faq* findest du eine schöne beschreibung zum pointer.

beitrag: pointer zeiger fifo lifo


----------



## Kai (13 Februar 2008)

Fabix schrieb:


> Ich habe in einem DB einen Bereich bei dem ich jedes gerade bit .7 auslesen möchte und in ein dw schreiben möchte.


 
Hallo Fabix,

hier ist mal ein kurzes Programmbeispiel:


```
FUNCTION FC 100 : VOID
TITLE =Bits lesen und speichern
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : BITS
VERSION : 1.0
 
VAR_INPUT
  QUELLE_ADRESSE : POINTER ;    
  QUELLE_LAENGE : INT ; 
  ZIEL_ADRESSE : POINTER ;  
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ;  
  AR1_REGISTER : DWORD ;    
  AR2_REGISTER : DWORD ;    
  QUELLE_DB_NUMMER : WORD ; 
  ZIEL_DB_NUMMER : WORD ;   
  SCHLEIFE : INT ;  
END_VAR
BEGIN
NETWORK
TITLE =DB-Register und Adressregister AR1 und AR2 sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
      TAR2  #AR2_REGISTER; // AR2-Register
 
NETWORK
TITLE =Bits lesen und speichern
 
      L     P##QUELLE_ADRESSE; // QUELLE POINTER
      LAR1  ; 
 
      L     W [AR1,P#0.0]; // QUELLE DB-Nummer
      T     #QUELLE_DB_NUMMER; 
 
      L     D [AR1,P#2.0]; // QUELLE Bereichszeiger 
      LAR1  ; 
 
 
      L     P##ZIEL_ADRESSE; // ZIEL POINTER
      LAR2  ; 
 
      L     W [AR2,P#0.0]; // ZIEL DB-Nummer
      T     #ZIEL_DB_NUMMER; 
 
      L     D [AR2,P#2.0]; // ZIEL Bereichszeiger
      LAR2  ; 
 
 
      L     #QUELLE_LAENGE; // QUELLE Länge
M01:  T     #SCHLEIFE; // Schleife
 
      AUF   DB [#QUELLE_DB_NUMMER]; // QUELLE Bit
      U      [AR1,P#0.7]; 
      AUF   DB [#ZIEL_DB_NUMMER]; // ZIEL Bit
      =      [AR2,P#0.0]; 
 
      L     P#2.0; // QUELLE Bereichszeiger
      +AR1  ; 
 
      L     P#0.1; // ZIEL Bereichszeiger
      +AR2  ; 
 
      L     #SCHLEIFE; // Schleife
      LOOP  M01; 
 
NETWORK
TITLE =DB-Register und Adressregister AR1 und AR2 wiederherstellen
 
      AUF   DB [#DB_REGISTER]; // DB-Register
 
      LAR1  #AR1_REGISTER; // AR1-Register
 
      LAR2  #AR2_REGISTER; // AR2-Register
 
END_FUNCTION
```
 
Gruß Kai


----------



## Fabix (15 Februar 2008)

*1 aus vielen*

Hallo Kai, 

genau soetwas habe ich gesucht. :-D

Vielen Dank. 

Gruß Fabix


----------

