Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 10 von 10

Thema: Bit-Feld in INT umwandeln

  1. #1
    Registriert seit
    05.07.2009
    Beiträge
    34
    Danke
    10
    Erhielt 1 Danke für 1 Beitrag

    Standard


    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
    Geändert von taylor1982 (13.11.2012 um 21:17 Uhr)
    Zitieren Zitieren Bit-Feld in INT umwandeln  

  2. #2
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.191
    Danke
    923
    Erhielt 3.292 Danke für 2.661 Beiträge

    Standard

    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
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  3. #3
    Registriert seit
    11.07.2004
    Beiträge
    1.597
    Danke
    10
    Erhielt 213 Danke für 183 Beiträge

    Standard

    Schleife programmieren, darin Wort für Wort betrachten, die beiden Bytes vertauschen, dann schauen welches Bit im Wort gesetzt ist (letzteres siehe z.B. hier: http://www.sps-forum.de/showthread.p...749#post297749 ). Wortnummer mal 16 plus Bit im Wort ergibt die Fehlernummer.

  4. #4
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.191
    Danke
    923
    Erhielt 3.292 Danke für 2.661 Beiträge

    Standard

    Ich würde die Bytes nicht tauschen.

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  5. #5
    Registriert seit
    20.03.2010
    Beiträge
    59
    Danke
    10
    Erhielt 9 Danke für 8 Beiträge

    Standard

    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
    Den Fortschritt verdanken die Menschen den Unzufriedenen.
    Aldous Huxley

  6. #6
    Registriert seit
    05.07.2009
    Beiträge
    34
    Danke
    10
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Danke schon mal für eure Tips. Das muss ich mir in einer ruhigen Minute mal anschauen.

    Zitat Zitat von PN/DP Beitrag anzeigen
    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.

  7. #7
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.191
    Danke
    923
    Erhielt 3.292 Danke für 2.661 Beiträge

    Standard

    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
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  8. #8
    Registriert seit
    20.03.2010
    Beiträge
    59
    Danke
    10
    Erhielt 9 Danke für 8 Beiträge

    Standard

    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
    Den Fortschritt verdanken die Menschen den Unzufriedenen.
    Aldous Huxley

  9. #9
    Registriert seit
    05.07.2009
    Beiträge
    34
    Danke
    10
    Erhielt 1 Danke für 1 Beitrag

    Standard

    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!

    Zitat Zitat von Pinky Beitrag anzeigen
    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

  10. #10
    Registriert seit
    20.03.2010
    Beiträge
    59
    Danke
    10
    Erhielt 9 Danke für 8 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Gern geschehen, schön das es funktioniert.
    Den Fortschritt verdanken die Menschen den Unzufriedenen.
    Aldous Huxley

Ähnliche Themen

  1. Datentypen Umwandeln INT=> TIME
    Von MS7315 im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 08.04.2012, 00:07
  2. INT Zahl in Kommazahl umwandeln
    Von Brian84 im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 06.04.2009, 13:51
  3. Real zahl in INT umwandeln
    Von bacardischmal im Forum Feldbusse
    Antworten: 5
    Letzter Beitrag: 20.03.2009, 18:17
  4. S7 Time in int umwandeln
    Von Jürgen.F im Forum Simatic
    Antworten: 8
    Letzter Beitrag: 25.09.2008, 16:23
  5. Int umwandeln
    Von kolbendosierer im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 28.03.2005, 13:16

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •