Bit-Feld in INT umwandeln

taylor1982

Level-2
Beiträge
34
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe folgendes mit Step7 V5.5 vor. Es gibt einen Datenbaustein, der die Fehlermeldungen zu WinCC beinhaltet. Damit in WinCC die Meldungen der Reihe nach aufgelegt werden können, hat der DB folgende Struktur (High- und Low-Byte sind gedreht:

Adr.
0.0 Fehler_09
0.1 Fehler_10
0.2 Fehler_11
0.3 Fehler_12
0.4 Fehler_13
0.5 Fehler_14
0.6 Fehler_15
0.7 Fehler_16
1.0 Fehler_01
1.1 Fehler_02
1.2 Fehler_03
1.3 Fehler_04
1.4 Fehler_05
1.5 Fehler_06
1.6 Fehler_07
1.7 Fehler_08
2.0 Fehler_17
usw.

Es existieren insgesamt ca. 1000 Fehlermeldungen. Nun soll zugleich wenn eine Fehlermeldung auftritt die Fehlernummer in eine INT-Variable gespeichert werden. Im Beispiel hier wenn also das DBX0.7 gesetzt ist, soll 16 in der Variable stehen.
Wie stellt man das am besten an? Wäre sehr über Tipps dankbar!

Gruß
Steve
 
Zuletzt bearbeitet:
Theoretisch reduziert sich Dein Problem in die Aufgabe, das niedrigste gesetzte Bit in einem (D)Word zu finden - benutze die Forumssuche nach BitPos.
Wieviele Bits können gleichzeitig gesetzt sein?

Harald
 
Ich hatte vor kurzem auch das selbe Problem. Habe mich daraufhin das erste mal mit SCL auseinandergesetzt und folgenden Baustein erstellt.
P.S.: Bevor man mich hier wegen Veröffentlichung groben Unfuges hier im Forum hängt möcht ich nur sagen das ich das Programm noch nicht testen konnte und ich vielleicht auch ein paar Tips bekomme was eventuell falsch ist oder was man besser machen könnte.
Vielen Dank

Code:
FUNCTION_BLOCK FB100
//***********************************************************************************************************************************
//Der FB durchsucht einen DB mit 1024 Störmeldungen und gibt die Störnummer am Ausgang aus.
//Sind mehrere Störungen auf "TRUE" so wird jede Störnummer min. 2sek im Wechsel nacheinander angezeigt.
//Der Baustein ist noch nicht getestet!!!!!!!!!!!!              
//***********************************************************************************************************************************
AUTHOR : Thomas
NAME : Anz Störnummer
VERSION : '1.0'
//vom 13.11.2012
//Vereinbarungsteil (Deklaration):
//--------------------------------
//Eingangsvariablen
VAR_INPUT
  Sperr_DB        : BLOCK_DB ;
  Sperr_Nr        : INT  := 0 ;
  Takt_10Hz       : BOOL := False ;
END_VAR
//---------------------------------
//Ausgangsvariablen
VAR_OUTPUT
  Anz_Sperr_Nr    : INT := 0 ;
END_VAR
//---------------------------------
//Durchgangsvariablen
VAR_IN_OUT
END_VAR
//---------------------------------
//Statische Variablen:
VAR  
HM                : ARRAY [0..7] OF BOOL ;        // Noch nicht eingesetzte Hilfsmerker: 4; 5; 6; 7;
Step              : INT := 0 ;                    // Schrittindex DB bitweise nach "TRUE" durchsuchen
Word_Index        : INT := 0 ;
Bit_Index         : INT := 0 ;
Bit_Maske         : WORD:= 0 ;
Anz_Stop          : BOOL:= FALSE ;                // Sperrt den Wechsel der Anzeige für die min Anzeigedauer (2sek)
Min_Anzeigezeit   : INT := 0 ;
END_VAR
//---------------------------------
//Temporäre Variablen:
VAR_TEMP
Wordnummer        : INT ;    
Wordadresse       : INT ;
Bitnummer         : INT ;
END_VAR
//----------------------------------
//Sprungmarken:
LABEL
SPRUNG_001 ;
No_Step_0 ;
No_Step_1 ;
No_Step_2 ;
No_Step_3 ;
END_LABEL

//Anweisungsteil (Programm):
//***********************************************************************************************************************************
BEGIN
        
// Durchsuche DB Bits nach "TRUE" und Ausgabe der Störnummern im 2Sek Takt
//--------------------------------------------------------------------------

// Schritt 0: Word_Index auf Ende? Wenn ja setze Index auf Anfang
//--------------------------------------------------------------------
IF Step <> 0 THEN                                     // Kein Schritt 0 
    GOTO No_Step_0 ;                                  // Überspringe Schritt 0
END_IF ;    
IF Bit_index > 15 THEN                                // Hat der Bit_index max überschritten
    Bit_index := 0 ;                                  // setze Bit_index auf 0
    Word_index:= Word_index+2 ;                       // erhöhe Word_index um 2( Wortadressierung nur über gerade Bytenummern)
    Step      := 1 ;                                  // Gehe zu Schritt 1

END_IF ;
No_Step_0: 
  
// Schritt 1: Bit_Index auf Ende ? Wenn ja Setze Bit_index auf "0" und erhöhe Word_index um "2"
//-----------------------------------------------------------------------------------------------
IF Step <> 1 THEN                                     // kein Schritt 1
    GOTO No_Step_1 ;                                  // Überspringe Schritt 1
END_IF ;   
IF Word_index > 127 THEN                              // Hat der Word_index max überschritten
    Word_index := 0 ;                                 // Setze Word_index auf 0
    Step       := 2 ;                                 // Gehe zu Schritt 2
END_IF ;    
No_Step_1:

// Schritt 2: Leerschritt
//-----------------------------------------------------------------------------
IF Step <> 2 THEN                                       // Kein Schritt 2
    GOTO No_Step_2 ;                                    // überspringe Schritt 2
    Step       := 3 ;                                   // setze Schritt 3
END_IF ;

No_Step_2:

// Schritt 3: Durchsuche Sperrword Bitweise auf "TRUE" und berechne und übergebe Störnummer an Anzeige
//--------------------------------------------------------------------------------------------------------
IF Step <> 3 OR Anz_Stop THEN                           // Kein Schritt 3 
    GOTO No_Step_3 ;                                    // überspringe Schritt 3
END_IF ;  
Bit_Maske := 2#0000_0000_0000_0001 ;                    // In Bitmaske das erste Bit auf "1" setzen
Bit_Maske := ROL(IN:=Bit_Maske, N:=Bit_index) ;         // Die "1" auf den richtigen Platz rotieren
  IF (Sperr_DB.DW[Word_index] AND Bit_Maske) = 0 THEN   // Falls der Bitvergleich "0" ist 
     Bit_index    := Bit_index+1 ;                      // erhöhe den Bit_index für die nächste Bitüberprüfung
     Step         := 0 ;                                // Setze Schritt 0
    GOTO No_Step_3 ;                                    // Überspringe Schritt 3
  ELSIF Anz_Stop = TRUE THEN                            // Minimale Anzeigezeit ist noch nicht abgelaufen
    GOTO No_Step_3 ;                                    // überspringe Schritt 3
  ELSIF (Sperr_DB.DW[Word_index] AND Bit_Maske) <> 0 THEN // Bitvergleich auf nicht Signal "0"
     Anz_Sperr_Nr := ((Word_index/2)*16)+(Bit_index+1) ;  // Wenn Bitvergleich "1" berechne Störnummer und sende zur Anzeige
     Anz_Stop     := TRUE ;                             // Sperre die Anzeige einer weiteren Störnummer bis die min. Anzeigezeit die Freigabe erteilt
     Bit_index    := Bit_index+1 ;                      // Erhöhe den Bit_index für die nächte Bitüberprüfung 
     Step         := 0 ;                                // Zurück zu Schritt 0
END_IF ;
    
No_Step_3:    

// Minimale Anzeigezeit (2Sekunden)
//------------------------------------
IF Anz_Stop = TRUE AND Takt_10Hz = TRUE AND HM[3] = FALSE THEN  // Erzeuge Zähltakt
    HM[3] := TRUE ;
    Min_Anzeigezeit := Min_Anzeigezeit+1 ;                      // Zähle Zeitspeicher hoch
ELSIF Takt_10Hz = FALSE THEN
    HM[3] := FALSE ;                                            // Rücksetze Hilfsmerker
END_IF ;

IF Min_Anzeigezeit = 20 THEN                                    // Abfrage ob 2 sek erreicht
    Anz_Stop := FALSE ;                                         // Wenn ja rücksetze Anzeigen Stop
    Min_Anzeigezeit := 0 ;                                      // und rücksetze Zeitspeicher
END_IF ;     
    //Programmende
    END_FUNCTION_BLOCK
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke schon mal für eure Tips. Das muss ich mir in einer ruhigen Minute mal anschauen.

Wieviele Bits können gleichzeitig gesetzt sein?
Harald

Theoretisch können alle Bits gesetzt sein. Allerdings sollen max. 8 INT-Werte mit Fehlernummern zum Leitsystem übertragen werden können.
 
Tja, dann brauchst Du eher so eine Lösung wie von Pinky (nicht getestet).

Was sagt das Leitsystem für den Fall, daß mehr als 8 Fehlermeldungen anstehen? Wie sollen die Nummern übertragen werden?
Sollen die Nummern auch noch in der richtigen Zeitfolge übertragen werden?

Ich würde wohl in jedem Zyklus alle 1000 Bits testen, und von denjenigen welche neu dazugekommen sind, die Fehlernummer in einen FIFO werfen. Das rausholen aus dem FIFO richtet sich dann danach, wie das Leitsystem es will. Da das ein serieller Prozess ist, kann es sogar vorkommen, daß Fehlernummern mehrmals kommen, bevor sie zum Leitsystem übertragen sind. Da besteht noch Abstimmungsbedarf mit dem Leitsystem. Möglicherweise wäre es auch besser, das gesamte Bitfeld zum Leitsystem zu übertragen - sollen die doch die Umrechnung in Fehlernummern machen.

Harald
 
Ich habe endlich mal den Baustein getestet und noch so einige Fehler gefunden und verschiedene Sachen geändert.
Für die gesuchte Funktion ist eigentlich nur der untere Teil wichtig.(Ab // Durchsuche DB Bits nach "TRUE" und.....)
Die Anzeigezeit könnte man ja dann sogar rausnehmen und den Ausgang in einen FIFO schieben.
Gute Nacht

Code:
FUNCTION_BLOCK FB100
//***********************************************************************************************************************************
//Der Baustein setzt oder rücksetzt ein Bit in einem DB mit 1024 boolschen Variablen. Die Anwahl des Bits erfolgt über eine Int-Zahl
//am Eingang :"Sperr_Nr". Die Nummerierung und Adressierung sind gleich mit den Störmeldungen im WinCC flexible. Über "Set" wird das 
//gewählte Bit gesetzt und über "Reset" wieder zurückgesetzt. "Reset_All" setzt alle Bits im DB auf Signal "0".
//Am Ausgang "Anz_Sperr_Nr" werden nacheinander alle auf "TRUE" gesetzten Bits für mindestens 2sek angezeigt.          
//***********************************************************************************************************************************
AUTHOR : 'T.H.'
NAME : 'Sperren'
VERSION : '1.0'
//vom 17.11.2012
//Vereinbarungsteil (Deklaration):
//--------------------------------
//Eingangsvariablen
VAR_INPUT
  Sperr_DB        : BLOCK_DB ;
  Sperr_Nr        : INT  := 0 ;
  Set             : BOOL := False ;
  Reset           : BOOL := False ;
  Reset_All       : BOOL := False ;
  Takt_10Hz       : BOOL := False ;
END_VAR
//---------------------------------
//Ausgangsvariablen
VAR_OUTPUT
Anz_Sperr_Nr      : INT := 0 ;
END_VAR
//---------------------------------
//Durchgangsvariablen
VAR_IN_OUT
END_VAR
//---------------------------------
//Statische Variablen:
VAR  
Loeschindex       : INT := 0 ;
HM                : ARRAY [0..7] OF BOOL ;        // Noch nicht eingesetzte Hilfsmerker: 4; 5; 6; 7;
Word_Index        : INT := 0 ;
Bit_Index         : INT := 0 ;
Anz_Stop          : BOOL:= FALSE ;                // Sperrt den Wechsel der Anzeige für die min Anzeigedauer (2sek)
Min_Anzeigezeit   : INT := 0 ;
END_VAR
//---------------------------------
//Temporäre Variablen:
VAR_TEMP
Wordnummer        : INT ;    
Wordadresse       : INT ;
Bitnummer         : INT ;
Bit_Maske         : WORD ;
END_VAR
//----------------------------------
//Sprungmarken:
LABEL
No_Choose ;
No_Anz ;
END_LABEL

//Anweisungsteil (Programm):
//***********************************************************************************************************************************
BEGIN
// Setze / Rücksetze Sperre
//---------------------------
IF Sperr_Nr <= 0 OR Sperr_Nr > 1024 THEN                      // Freigabe
    GOTO No_Choose  ;
ELSIF Sperr_Nr > 0 THEN                                      // Berechnung Wordadresse 
    Wordadresse    := ((Sperr_nr-1)/16)*2 ;
    Bitnummer      := (Sperr_Nr-1)-(Wordnummer*16) ;         // Berechnung Bitnummer
END_IF ; 
 
IF Set  = TRUE AND HM[0] = FALSE THEN                        // Erzeuge Setzimpuls
    HM[0] := TRUE ;                                       
    Bit_Maske     := 2#0000_0000_0000_0001 ;                 // Setze Alle Bits auf "False" nur Bit 0 auf "TRUE"
    Bit_Maske     := ROL(IN:= Bit_Maske, N:=Bitnummer) ;  // Rotiere "TRUE" auf richtige Position
    Sperr_DB.DW[Wordadresse] := Bit_Maske  OR Sperr_DB.DW[Wordadresse];    // Schreibe Ergebnis in Datenbaustein ohne andere Bits zu verändern
ELSIF Set = FALSE AND HM[0] = TRUE THEN
    HM[0] := FALSE ;                                         // Hilfsmerker Flanke zurücksetzen
 END_IF ;    
   
    // Rücksetzen Bit
IF Reset  = TRUE AND HM[1] = FALSE THEN                      // Erzeuge Rücksetzimpuls
    HM[0] := TRUE ;                                       
    Bit_Maske     := 2#1111_1111_1111_1110  ;                // Setze alle Bits auf "TRUE" nur Bit 0 auf "False"                                     
    Bit_Maske     := ROL(IN:= Bit_Maske, N:=Bitnummer) ;  // Rotiere "FALSE" auf richtige Position
    Sperr_DB.DW[Wordadresse] := Bit_Maske  AND Sperr_DB.DW[Wordadresse] ;  // Schreibe Ergebnis in Datenbaustein ohne die anderen Bits zu beeinflussen
ELSIF Reset = FALSE AND HM[1] THEN
    HM[1] := FALSE ;                                         // Hilfsmerker Flanke zurücksetzen
 END_IF ;    

No_Choose: 

// Alles zurücksetzen
//---------------------
 
IF Reset_All = TRUE AND HM[2] = FALSE THEN        // Impuls setzen für Reset All
    HM[2] := TRUE ;
    Loeschindex := 0 ;                            // Setze Löschindex einmalig auf 0 
  REPEAT
    Sperr_DB.DW[Loeschindex] := 0 ;               // Schreibe 0 in Datenwort
    Loeschindex  := Loeschindex +2 ;              // Index erhöhen für nächstes Datenwort
  UNTIL Loeschindex = 128                         // Bis Endadresse erreicht ist
  END_REPEAT ;
ELSIF Reset_All = FALSE THEN                      // Rücksetze Hilfsmerker
    HM[2] := FALSE ;
END_IF ;
        
// Durchsuche DB Bits nach "TRUE" und Ausgabe der Sperrnummern im 2Sek Takt
//--------------------------------------------------------------------------
IF Word_index = 126 AND Bit_index > 15 AND Anz_Stop = TRUE THEN // Word_index und Bit_index auf max und Mindestanzeigedauer ist noch nicht abgelaufen
   GOTO No_Anz ;                                                // Überspringe Suchfunktion
END_IF ;   
  
// Bit_Index über Ende? Wenn ja Setze Bit_index auf "0" und erhöhe Word_index um "2"
//-----------------------------------------------------------------------------------------------
IF Bit_index > 15 THEN                                          // Hat der Bit_index max überschritten
    Bit_index := 0 ;                                            // setze Bit_index auf 0
    Word_index:= Word_index+2 ;                                 // erhöhe Word_index um 2( Wortadressierung nur über gerade Bytenummern) 
END_IF ;    

// Word_Index auf Ende? Wenn ja setze Index auf Anfang
//--------------------------------------------------------------------
IF Word_index >= 128 THEN                                       // Hat der Word_index max überschritten
    Word_index := 0 ;                                           // Setze Word_index auf 0 
    Anz_Sperr_Nr := 0 ;                                         // Lösche Anzeige
END_IF ;

// Durchsuche Sperrword Bitweise auf "TRUE" und berechne und übergebe Sperrnummer an Anzeige
//--------------------------------------------------------------------------------------------------------
Bit_Maske := 2#0000_0000_0000_0001 ;                            // In Bitmaske das erste Bit auf "1" setzen
Bit_Maske := ROL(IN:=Bit_Maske, N:=Bit_index) ;                 // Die "1" auf den richtigen Platz rotieren
  IF (Sperr_DB.DW[Word_index] AND Bit_Maske) = 0 THEN           // Falls der Bitvergleich "0" ist 
     Bit_index    := Bit_index+1 ;                              // erhöhe den Bit_index für die nächste Bitüberprüfung
    GOTO No_Anz ;                                               // Überspringe Ausgabe auf Anzeige
  ELSIF (Sperr_DB.DW[Word_index] AND Bit_Maske) <> 0 AND Anz_Stop = FALSE THEN       // Bitvergleich auf nicht Signal "0"
     Anz_Sperr_Nr := ((Word_index/2)*16)+(Bit_index+1) ;        // Wenn Bitvergleich "1" berechne Sperrnummer und sende zur Anzeige
     Anz_Stop     := TRUE ;                                     // Sperre die Anzeige einer weiteren Sperrnummer bis die min. Anzeigezeit die Freigabe erteilt
     Bit_index    := Bit_index+1 ;                              // Erhöhe den Bit_index für die nächte Bitüberprüfung 
END_IF ;
    No_Anz:    

// Minimale Anzeigezeit (2Sekunden)
//------------------------------------
IF Anz_Stop = TRUE AND Takt_10Hz = TRUE AND HM[3] = FALSE THEN  // Erzeuge Zähltakt
    HM[3] := TRUE ;
    Min_Anzeigezeit := Min_Anzeigezeit+1 ;                      // Zähle Zeitspeicher hoch
ELSIF Takt_10Hz = FALSE THEN
    HM[3] := FALSE ;                                            // Rücksetze Hilfsmerker
END_IF ;

IF Min_Anzeigezeit = 20 THEN                                    // Abfrage ob 2 sek erreicht
    Anz_Stop := FALSE ;                                         // Wenn ja rücksetze Anzeigen Stop
    Min_Anzeigezeit := 0 ;                                      // und rücksetze Zeitspeicher
END_IF ;     
    //Programmende
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi Pinky,

vielen Dank für dein Beispiel. Hab dies mal als Grundlage verwendet und noch einen FIFO hinten dran gebastelt. So war es in kurzer Zeit möglich diese Funktion umzusetzen. Vielen Dank!

Ich habe endlich mal den Baustein getestet und noch so einige Fehler gefunden und verschiedene Sachen geändert.
Für die gesuchte Funktion ist eigentlich nur der untere Teil wichtig.(Ab // Durchsuche DB Bits nach "TRUE" und.....)
Die Anzeigezeit könnte man ja dann sogar rausnehmen und den Ausgang in einen FIFO schieben.
Gute Nacht

Code:
FUNCTION_BLOCK FB100
//***********************************************************************************************************************************
//Der Baustein setzt oder rücksetzt ein Bit in einem DB mit 1024 boolschen Variablen. Die Anwahl des Bits erfolgt über eine Int-Zahl
//am Eingang :"Sperr_Nr". Die Nummerierung und Adressierung sind gleich mit den Störmeldungen im WinCC flexible. Über "Set" wird das 
//gewählte Bit gesetzt und über "Reset" wieder zurückgesetzt. "Reset_All" setzt alle Bits im DB auf Signal "0".
//Am Ausgang "Anz_Sperr_Nr" werden nacheinander alle auf "TRUE" gesetzten Bits für mindestens 2sek angezeigt.          
//***********************************************************************************************************************************
AUTHOR : 'T.H.'
NAME : 'Sperren'
VERSION : '1.0'
//vom 17.11.2012
//Vereinbarungsteil (Deklaration):
//--------------------------------
//Eingangsvariablen
VAR_INPUT
  Sperr_DB        : BLOCK_DB ;
  Sperr_Nr        : INT  := 0 ;
  Set             : BOOL := False ;
  Reset           : BOOL := False ;
  Reset_All       : BOOL := False ;
  Takt_10Hz       : BOOL := False ;
END_VAR
//---------------------------------
//Ausgangsvariablen
VAR_OUTPUT
Anz_Sperr_Nr      : INT := 0 ;
END_VAR
//---------------------------------
//Durchgangsvariablen
VAR_IN_OUT
END_VAR
//---------------------------------
//Statische Variablen:
VAR  
Loeschindex       : INT := 0 ;
HM                : ARRAY [0..7] OF BOOL ;        // Noch nicht eingesetzte Hilfsmerker: 4; 5; 6; 7;
Word_Index        : INT := 0 ;
Bit_Index         : INT := 0 ;
Anz_Stop          : BOOL:= FALSE ;                // Sperrt den Wechsel der Anzeige für die min Anzeigedauer (2sek)
Min_Anzeigezeit   : INT := 0 ;
END_VAR
//---------------------------------
//Temporäre Variablen:
VAR_TEMP
Wordnummer        : INT ;    
Wordadresse       : INT ;
Bitnummer         : INT ;
Bit_Maske         : WORD ;
END_VAR
//----------------------------------
//Sprungmarken:
LABEL
No_Choose ;
No_Anz ;
END_LABEL

//Anweisungsteil (Programm):
//***********************************************************************************************************************************
BEGIN
// Setze / Rücksetze Sperre
//---------------------------
IF Sperr_Nr <= 0 OR Sperr_Nr > 1024 THEN                      // Freigabe
    GOTO No_Choose  ;
ELSIF Sperr_Nr > 0 THEN                                      // Berechnung Wordadresse 
    Wordadresse    := ((Sperr_nr-1)/16)*2 ;
    Bitnummer      := (Sperr_Nr-1)-(Wordnummer*16) ;         // Berechnung Bitnummer
END_IF ; 
 
IF Set  = TRUE AND HM[0] = FALSE THEN                        // Erzeuge Setzimpuls
    HM[0] := TRUE ;                                       
    Bit_Maske     := 2#0000_0000_0000_0001 ;                 // Setze Alle Bits auf "False" nur Bit 0 auf "TRUE"
    Bit_Maske     := ROL(IN:= Bit_Maske, N:=Bitnummer) ;  // Rotiere "TRUE" auf richtige Position
    Sperr_DB.DW[Wordadresse] := Bit_Maske  OR Sperr_DB.DW[Wordadresse];    // Schreibe Ergebnis in Datenbaustein ohne andere Bits zu verändern
ELSIF Set = FALSE AND HM[0] = TRUE THEN
    HM[0] := FALSE ;                                         // Hilfsmerker Flanke zurücksetzen
 END_IF ;    
   
    // Rücksetzen Bit
IF Reset  = TRUE AND HM[1] = FALSE THEN                      // Erzeuge Rücksetzimpuls
    HM[0] := TRUE ;                                       
    Bit_Maske     := 2#1111_1111_1111_1110  ;                // Setze alle Bits auf "TRUE" nur Bit 0 auf "False"                                     
    Bit_Maske     := ROL(IN:= Bit_Maske, N:=Bitnummer) ;  // Rotiere "FALSE" auf richtige Position
    Sperr_DB.DW[Wordadresse] := Bit_Maske  AND Sperr_DB.DW[Wordadresse] ;  // Schreibe Ergebnis in Datenbaustein ohne die anderen Bits zu beeinflussen
ELSIF Reset = FALSE AND HM[1] THEN
    HM[1] := FALSE ;                                         // Hilfsmerker Flanke zurücksetzen
 END_IF ;    

No_Choose: 

// Alles zurücksetzen
//---------------------
 
IF Reset_All = TRUE AND HM[2] = FALSE THEN        // Impuls setzen für Reset All
    HM[2] := TRUE ;
    Loeschindex := 0 ;                            // Setze Löschindex einmalig auf 0 
  REPEAT
    Sperr_DB.DW[Loeschindex] := 0 ;               // Schreibe 0 in Datenwort
    Loeschindex  := Loeschindex +2 ;              // Index erhöhen für nächstes Datenwort
  UNTIL Loeschindex = 128                         // Bis Endadresse erreicht ist
  END_REPEAT ;
ELSIF Reset_All = FALSE THEN                      // Rücksetze Hilfsmerker
    HM[2] := FALSE ;
END_IF ;
        
// Durchsuche DB Bits nach "TRUE" und Ausgabe der Sperrnummern im 2Sek Takt
//--------------------------------------------------------------------------
IF Word_index = 126 AND Bit_index > 15 AND Anz_Stop = TRUE THEN // Word_index und Bit_index auf max und Mindestanzeigedauer ist noch nicht abgelaufen
   GOTO No_Anz ;                                                // Überspringe Suchfunktion
END_IF ;   
  
// Bit_Index über Ende? Wenn ja Setze Bit_index auf "0" und erhöhe Word_index um "2"
//-----------------------------------------------------------------------------------------------
IF Bit_index > 15 THEN                                          // Hat der Bit_index max überschritten
    Bit_index := 0 ;                                            // setze Bit_index auf 0
    Word_index:= Word_index+2 ;                                 // erhöhe Word_index um 2( Wortadressierung nur über gerade Bytenummern) 
END_IF ;    

// Word_Index auf Ende? Wenn ja setze Index auf Anfang
//--------------------------------------------------------------------
IF Word_index >= 128 THEN                                       // Hat der Word_index max überschritten
    Word_index := 0 ;                                           // Setze Word_index auf 0 
    Anz_Sperr_Nr := 0 ;                                         // Lösche Anzeige
END_IF ;

// Durchsuche Sperrword Bitweise auf "TRUE" und berechne und übergebe Sperrnummer an Anzeige
//--------------------------------------------------------------------------------------------------------
Bit_Maske := 2#0000_0000_0000_0001 ;                            // In Bitmaske das erste Bit auf "1" setzen
Bit_Maske := ROL(IN:=Bit_Maske, N:=Bit_index) ;                 // Die "1" auf den richtigen Platz rotieren
  IF (Sperr_DB.DW[Word_index] AND Bit_Maske) = 0 THEN           // Falls der Bitvergleich "0" ist 
     Bit_index    := Bit_index+1 ;                              // erhöhe den Bit_index für die nächste Bitüberprüfung
    GOTO No_Anz ;                                               // Überspringe Ausgabe auf Anzeige
  ELSIF (Sperr_DB.DW[Word_index] AND Bit_Maske) <> 0 AND Anz_Stop = FALSE THEN       // Bitvergleich auf nicht Signal "0"
     Anz_Sperr_Nr := ((Word_index/2)*16)+(Bit_index+1) ;        // Wenn Bitvergleich "1" berechne Sperrnummer und sende zur Anzeige
     Anz_Stop     := TRUE ;                                     // Sperre die Anzeige einer weiteren Sperrnummer bis die min. Anzeigezeit die Freigabe erteilt
     Bit_index    := Bit_index+1 ;                              // Erhöhe den Bit_index für die nächte Bitüberprüfung 
END_IF ;
    No_Anz:    

// Minimale Anzeigezeit (2Sekunden)
//------------------------------------
IF Anz_Stop = TRUE AND Takt_10Hz = TRUE AND HM[3] = FALSE THEN  // Erzeuge Zähltakt
    HM[3] := TRUE ;
    Min_Anzeigezeit := Min_Anzeigezeit+1 ;                      // Zähle Zeitspeicher hoch
ELSIF Takt_10Hz = FALSE THEN
    HM[3] := FALSE ;                                            // Rücksetze Hilfsmerker
END_IF ;

IF Min_Anzeigezeit = 20 THEN                                    // Abfrage ob 2 sek erreicht
    Anz_Stop := FALSE ;                                         // Wenn ja rücksetze Anzeigen Stop
    Min_Anzeigezeit := 0 ;                                      // und rücksetze Zeitspeicher
END_IF ;     
    //Programmende
 
Zurück
Oben