# Schieberegister mit S7-300



## Spag (6 August 2008)

Hallo,

ich soll ein Schieberegister programmieren, das durch einen Interrupt aufgerufen wird. Dann soll es verschiedenen Werte abfragen und je nachdem weiterschieben und 0 oder A eintragen. Soweit hab ich es eigentlich schon.
Nur soll bei einem Not Aus bestimmte Bereiche, die mit A belegt sind, als schlecht gekennzeichnet werden und dann ausgeworfen. Wie kann ich bei dem Schieberegister einen Teil des Arrays auf A prüfen und dann das A in B ändern?

Danke für eure Hilfe!
Spag


----------



## Larry Laffer (6 August 2008)

...
Wie ist dein "Schieberegister" denn aufgebaut ?
ARRAY of Byte (oder größer oder wirklich ein Bit-Register) ?
Gib mal ein paar mehr Info's ...

Gruß
LL


----------



## Ralle (6 August 2008)

Deine Fragestellung ist nicht sehr aussagekräftig, da sehr allgemein. Programmierst du mit SCL oder AWL. In SCl geht das recht eindach, mit einem Index kann man in einer Schleife durch das Array laufen, den Vergleich machen und dann bei Bedarf einen neuen Wert (hier "B") in das Arrayelement eintragen.

In AWL ist das ein klein wenig komplizierter, du benötigst indirekte Adressierung. Siehe dazu zuerst bitte mal in der FAQ und im Forum unter "FIFO", "LIFO", "indirekte Adressierung", "Pointer". Da wird sich schon eine Menge finden.


----------



## Spag (6 August 2008)

@Larry
Ja das ist ein Array of Byte.
Ich will erkennen, ob in einem bestimmten Toleranzbereich ein Signal kommt. Dazu werde ich vom OB35 immer wieder aufgerufen und frage den Stand von Toleranzbereich und Signaleingang ab. Wenn ein Signal da ist, wird gezählt. Wenn der Toleranzbereich eine negative Flanke macht, wird ausgewertet. Die Flanke löst erstmal ein schieben des Registers aus und wenn der Zählerwert einen vordefinierten Wert überschritten hat, dann wird ein A eingeschrieben, sonst eine 0. In beiden Fällen wird dann der Zähler zurückgesetzt.
Das funktioniert jetzt endlich auch.
Dann möchte ich bei NotAus einen Teil des Arrays auf das A abfragen und es durch B ersetzen, damit der Auswerfer weiß, dass er dann aktiv werden muss.

@Ralle
Ich programmiere in AWL und das noch nicht sehr lange..daher wohl auch die allgemeine Fragestellung. SCL wird hier auch verwendet, aber egtl nur für die komplizierteren Teile, auf die nur wenige Leute Zugriff haben...also ich nicht  Danke für die Stichworte, werde mir das mal durchlesen.

Gruß, Spag


----------



## Ralle (6 August 2008)

ok, hier mal ein Stück Code, das eine sehr einfache Methode zur indirekten Adressierung nutzt und in einer Schleife 30 Byte von 0-30 durchsucht.


```
AUF   "COUNT_DB"            //zu durchsuchender DB

      L     P#0.0                       //Pointer auf Start im DB, hier DBB0
      T     #pointer_1                  //temp DWORD

      L     30                          //Anzahl der Byte, die durchsucht werden
SC02: T     #zaehler                    //temp INT

      L     DBB [#pointer_1]            // Lade Datenbyte
      L     'A'                         // Lade 'A'
      <>I                               // ungleich?
      SPB   NUL2                        // nicht tauschen
      L     'B'                         // Schreibe 'B'
      T     DBB [#pointer_1] 

NUL2: NOP   0                           // Zeiger erhöhen auf nächstest DBB
      L     #pointer_1
      L     P#1.0
      +D    
      T     #pointer_1
      L     #zaehler
      LOOP  SC02                        // Schleife solange, bis #zaehler auf 0
```
Noch ein Hinweis, statt z.Bsp. 

L P#10.0  (du willst ab Adresse 10 im DB suchen)

kann man auch eine Int-Zahl übergeben und diese so behandeln:

L 10
SLD 3
T #pointer_1

Damit läßt sich der Suchbereich leichter variabel gestalten!


----------



## Spag (6 August 2008)

Danke, werde ich gleich mal ausprobieren!

Wenn ich die Int Zahl übergebe, welchen Datentyp braucht dann der #pointer_1?


----------



## Ralle (6 August 2008)

Spag schrieb:


> Danke, werde ich gleich mal ausprobieren!
> 
> Wenn ich die Int Zahl übergebe, welchen Datentyp braucht dann der #pointer_1?



DWORD, kann im Temp-Bereich des Bausteins angelegt werden.
Achtung, eine Loop wird in einem SPS-Zyklus komplett duchlaufen. Wenn also eine sehr lange Schleife abgearbeitet wird, schlägt sich das evtl. negativ auf die Zykluszeit nieder. Kannst ja mal mit dem Code experimentieren.


----------



## Spag (6 August 2008)

Das soll etwa 60 Bytes überprüfen, nachdem der NotAus wieder weg ist und bevor die Maschine wieder los geht. Die Zykluszeitüberwachung ist auf 150ms eingestellt...sollte also kein Problem darstellen, oder?


----------



## Spag (6 August 2008)

Bei mir sieht das jetzt so aus:

```
AUF   "COUNT_DB"            //zu durchsuchender DB

      L     #versatz                      //in INT
      SLD 3
      T #pointer_1                  //temp DWORD

         L     #byteanzahl                          //in INT
SC02: T     #zaehler                    //temp INT

      L     DBB [#pointer_1]            // Lade Datenbyte
      L     'A'                         // Lade 'A'
      <>I                               // ungleich?
      SPB   NUL2                        // nicht tauschen
      L     'B'                         // Schreibe 'B'
      T     DBB [#pointer_1] 

NUL2: NOP   0                           // Zeiger erhöhen auf nächstest DBB
      L     #pointer_1
      L     P#1.0
      +D    
      T     #pointer_1
      L     #zaehler
      LOOP  SC02                        // Schleife solange, bis #zaehler auf 0
```

Nur werden die A nicht in B gewandelt...
...und mir kommt auch grad wieso nicht...das A ist eine DEZ 10 in HEX...und ich suche nach Buchstaben...


----------



## Larry Laffer (6 August 2008)

... dann könntest du schreiben :

```
L w#16#a
 
bzw.
 
L w#16#b
 
oder in dezimal
 
L 10 bzw. 11
```
Gruß
LL


----------



## vierlagig (6 August 2008)

Larry Laffer schrieb:


> ... dann könntest du schreiben



imho ist es egal ob du 'A' als char oder A als hex oder 10 in dez lädst ... da kommt immer das selbe raus und wird vom vergleicher auch so interpretiert, da er die akkuinhalte vergleicht und es ihm herzlichst egal ist ob da nun char mit dez oder hex mit real verglichen wird ... zumindest in AWL


----------



## Larry Laffer (6 August 2008)

@4L:
 der Char-Wert von 'A' ist nicht gleich 10 (dezimal) sondern 65 (oder 41 in Hex)


----------



## vierlagig (6 August 2008)

Larry Laffer schrieb:


> @4L:
> der Char-Wert von 'A' ist nicht gleich 10 (dezimal) sondern 65 (oder 41 in Hex)



ups ...  ...warum das? wer läßt sich sone sch*** einfallen?


----------



## Ralle (6 August 2008)

Ich war von Char ausgegangen, ansonsten siehe LL, du mußt halt in der Vergleicher das als Wert schreiben, was auch im DB steht, dann funzt das schon .


----------



## Spag (6 August 2008)

Das mit dem Typ hatte ich vergessen zu erwähnen...wie gesagt ist mir das ja in dem Moment als ich es geschrieben hab klar geworden, dass ich dann HEX Werte brauch...und geändert ist es auch schon. Funktioniert super. Vielen Dank für die Hilfe!


----------



## HaDi (6 August 2008)

vierlagig schrieb:


> ups ...  ...warum das? wer läßt sich sone sch*** einfallen?


Die Amis, wer sonst...

ASCII

Grüße von HaDi


----------

