# Sortierbasutein mit Any Pointer



## stevexxx (9 April 2008)

muss einen Baustein schreiben der mir Bytebereiche in einem DB sortiert

IN Start Bool
IN DB_Nr  Word
IN Startadresse INT
IN Anzahl Worde INT
IN Sortierbereich Word  (in Byte)  sprich blockweise sortierung
OUT Sortieren Fertig Bool


da ich noch nie mit Any pointern gearbeitet habe  stellt sich das ganze als schwierig heraus... vorallem wenn ich anypointer miteinander vergleichen will und dann die Werte nach Größe Sortieren



vl kann mir ja jemand weiterhelfen

(habe die Sufu verwendet aber nichts brauchbares in Richtung any-pointer gefunden)



lg steve


----------



## marlob (9 April 2008)

stevexxx schrieb:


> …
> (habe die Sufu verwendet aber nichts brauchbares in Richtung any-pointer gefunden)
> 
> 
> ...


Dann suche mal nach sortieren bzw. bubblesort


----------



## stevexxx (9 April 2008)

das habe ich ja schon gefunden aber da werden keine anypointer verglichen hmm...


----------



## Larry Laffer (9 April 2008)

Die von dir angegebenen Aufruf-Parameter haben für mich erstmal nichts mit ANY-Pointern zu tun.
Wenn du zum Thema ANY-Pointer Info's brauchst, dann gibt es dazu in der Rubrik FAQ einen schönen Beitrag. Den solltest du erstmal lesen.
Zum Thema Sortier-Funktion entweder wie von Marlob sdchon genannt oder alternativ mal "Bubblesort" versuchen.

Gruß
LL


----------



## stevexxx (9 April 2008)

IN Sortierbereich Word (in Byte) sprich blockweise sortierung zum thema Any Pointer.....


nehmen wir mal an in meinem db ist 15 wörter lang

wenn der sortier bereich auf 3 byte eingestellt ist wird b0.0 bis 2.7

und 3.0 bis 4.7 miteinander verglichen (im block)

somit hab ich bei 15 wörtern 30 byte  sprich 30 Blöcke die ich miteinander vergleiche und die ich dann in meinem db der größe nach sortieren muss....


----------



## Larry Laffer (9 April 2008)

Es gibt in Step7 keine 3-Byte-Variablen ...
Wenn du es dir nicht unnötig kompliziert machen willst, dann solltest du dich für das Sortieren an gängige Variablen-Formate halten - nur so als Tip.
Das andere geht natürlich auch - ist halt immer eine Frage, wieviel Arbeit man sich machen möchte ...


----------



## stevexxx (9 April 2008)

i red nicht von Variablen sondern einem bereich den ich über anypointer einstellen kann     

und diese bereiche vergleiche ich dann miteinander... es gibt keine andre lösung     und über dem parameter sortierbereich wird die wiederholrate des anypointer eingestellt   sprich  wenn der wert auf byte eingestellt ist sind das dann 3 byte ide ioch mir ansehe


----------



## Larry Laffer (9 April 2008)

Wenn du etwas Sortieren oder verrechnen willst, so geht das nicht mit Bereichen  es sei denn du baust dir dafür eine Funktion, die die Inhalte der bereiche miteinander sinnvoll vergeicht.
Du kannst nur Variablen miteinander vergleichen.
Der ANY-Pointer ist nur ein Zeiger auf eine Variable (oder einen Bereich).
Wenn du einen speziellen Algorythmus benötigst, dann solltest du dir erstmal darüber Gedanken machen. Nach meiner Einschätzung (aber das hatte ich schon erwähnt) benötigst du erstmal keinen ANY-Pointer und der hilft dir auch bei nichts ...


----------



## stevexxx (9 April 2008)

wie soll ich ohne anypointer bereiche vergleichen?? *lol*  des geht ja nicht ohne dem   ...

der bereich muss variabel einstellbar sein (Byteweise)
deswegn ist das ganze ein bisschen heavy finde ich

INT Werte miteinander vergleichen ist keine Kunst
aber einzelne BEreiche hingegen für mich im moment sehr schwer


lg steve


----------



## Larry Laffer (9 April 2008)

Vielleicht liest du dir mal diesen Beitrag durch :
http://www.sps-forum.de/showthread.php?t=8887

Dein Stichwort heißt Schleifen-Programmierung und nicht ANY-Pointer.


----------



## stevexxx (9 April 2008)

eigentlich muss ich mir nur das erste byte im bereich anschaun... und mit dem ersten vom 2 ten bereich vergleichen...

des transferieren des bereiches könnte ich dann wieder einzeln machn oder mit any


----------



## Larry Laffer (9 April 2008)

... und für alles das nimmt man die indirekte Adressierung her und das dann in einer Bearbeitungs-Schleife.

Der ANY-Pointern ist eine Möglichkeit die Adresse einer Variablen oder eines Bereiches an eine andere Funktion zu übergeben. In dieser Funktion wird der ANY-Pointer dann wieder zerlegt um eine Schleifen-Bearbeitung zu ermöglichen ...


----------



## stevexxx (9 April 2008)

hmmm das ganze könnte sich als schwierig erweisen bei negativen zahlen was i mal nicht hoffe das solche werte vorkommen   
dann muss ich aufs vorzeichen auch noch achten ;(

oje oje


----------



## centrox (9 April 2008)

stevexxx schrieb:


> hmmm das ganze könnte sich als schwierig erweisen bei negativen zahlen was i mal nicht hoffe das solche werte vorkommen
> dann muss ich aufs vorzeichen auch noch achten ;(
> oje oje



spielt doch keine Rolle ob negativ oder nicht für den Vergleich.

Ich würd an deiner Stelle mich unbedingt einarbeiten in die Themen: Indirekte Adressierung, Adressregister allgemein, Aufbau Any Pointer (den kann man als Eingangsparameter bei deiner Funktion durchaus gebrauchen), Schleifen.

Was ganz wichtig ist, einen sauberer Programmierstil ans Tageslicht wenns um solche Geschichten geht, und mit den Kommentaren nicht sparsam sein, den Code blickst du sonst 3 Monate später nicht mal mehr selbst.

und sonst hello@all
Hab mich heut mal hier angemeldet, lies zwar schon länger mit und hab mir auch schon den ein oder anderen Tipp hier holen können, jedoch es heute erst geschafft mich mal anzumelden und etwas zu schreiben.

Viele grüße 
centrox


----------



## stevexxx (9 April 2008)

spielt schon ne rolle ob pos oder neg... die ersten drei stellen sind ja das vorzeichen naja egal....



L     #iDB_Nr
  T     #tDb_Nr
  U     #iStart
  FP    #sm1
  SPBN  exit

      AUF   DB [#tDb_Nr]                
M002: LAR1  P##iStartadresse
  SET   
  S     #oSort_done
  L     #iAnz_Werte
  L     1
        -I    
LOOP: T     #sCount                     
      L     B [AR1,P#0.0]
      L     B [AR1,P#1.0]
      <=I   
      SPB   M003
      L     B [AR1,P#0.0]
      T     #tTemp
      L     B [AR1,P#1.0]
      T     B [AR1,P#0.0]
      L     #tTemp
      T     B [AR1,P#1.0]
      SET   
      R     #oSort_done
M003: TAR1  
      L     8
      +D    
      LAR1  
      L     #sCount
      UN    #oSort_done
      SPB   M002
      BE    
exit: NOP   0​ 


wollts mal byteweise ausprobiern funktioniert aber nicht wirklich bei mir hmm...


----------



## Larry Laffer (9 April 2008)

... ich kann da in deinem Beispiel auch keine wirkliche Schleife erkennen ...

Was soll denn grundsätzlich dabei heraus kommen ...?
Von wo bis wo willst du nach welchen Kriterien sortieren und was ?


----------



## stevexxx (9 April 2008)

Loopschleife.....

 ja größter wert nkommt ganz nach rechts

sprich aufsteigend sortieren


----------



## Larry Laffer (9 April 2008)

Bitte meine Frage beantworten und nicht irgend etwas in Stichworten ...


----------



## vierlagig (9 April 2008)

Larry Laffer schrieb:


> Bitte meine Frage beantworten und nicht irgend etwas in Stichworten ...



*ACK* ... er wäre nicht der erste, der *hier* landet 

[edit] [code ] und [/code ] (jeweils ohne space) machen code lesbarer [/edit]


----------



## stevexxx (9 April 2008)

Ich vergleiche die Werte und ordne sie nach Ihrer größe

in dem Programmbeispiel werden immer 2 Werte miteinander verglichen
ist der erste wert größer als der zweite so wird er mit diesem ausgetauscht
ist das nicht der fall so wird er mit dem 3-ten verglichen


bubble sort prinzip


----------



## Larry Laffer (9 April 2008)

So, wie du das realisiert hast vergleichst du 2 Bytes mit einander und tauscht die aus (ggf.).
Wie steht das Ganze jetzt mit deinem 3-Byte-Gedanken vom Anfang in Verbindung und welcher Sinn steckt dahinter.

Außerdem ... ich kann in deinem Code-Beispiel keine Schleife und keine Pointer-Erhöhung erkennen ... Liegt aber vielleicht auch an meinem fortgeschrittenen Alter ...


----------



## stevexxx (9 April 2008)

hab das 3 byte vergleich... mal zur seite gelegt und fang mit etwas leichterem an...


also pointer erkennst du keinen  >>>>  L dbb[ar1,p#0.0]  zb.


ja ich probier mal einen DB welcher mit 10 Byte Werten gefüllt ist zu sortieren


den code dazu habe ich ja schon gepostet  funktioniert aber irgendwie nicth... (eigentlich 0)


lg steve


----------



## centrox (9 April 2008)

So kommen wir dem ganzen etwas näher...
Wo stehen die Werte, ich nehm mal an in einem Array...
Wie viele Werte sind es, immer gleich viele???


----------



## stevexxx (9 April 2008)

hab momentan ein array mit 10 Byte


programm soll aber variabel  gestaltet sein


----------



## centrox (9 April 2008)

OK, mal ein Anfang,
nimms mir nicht übel, aber ich glaub du hast noch keinen blassen Schimmer von indirekter Adressierung. Ist ja auch nicht schlimm, jeder hat mal angefangen. Mach dich mal damit vertraut, und dann wird das schon.
kleines Beispiel:


```
L  dw#16#84000000
LAR1

auf [#DBin]

L  B [ar1, p#0.0]
L  B [ar1, p#1.0]
==I
...
```
Wär jetzt nur mal ein Beispiel wie das erste Byte mit dem zweiten verglichen werden kann, nur mal so als kleiner Anstoss. Aber wie gesagt erst mal mit dem Aufbau des Adressregisters und co vertraut...


----------



## Larry Laffer (9 April 2008)

Das mit dem DB-Aufruf und dem Register hat Steve schon richtig drin.
Mit dem Zeiger auf die erste Adresse hapert es aber dann schon.

Steve hat in seinem Code :
	
	



```
M002: LAR1 P##iStartadresse
```
So würde ich es nicht machen.
Start-Adresse ist ja warscheinlich die Nummer des ersten Bytes ...?

Also müßte es heissen :
	
	



```
L iStartadresse
ITD
T hPointer      // DWORD im TEMP-Bereich
 
LOOP: L hPointer
SLD 3
LAR1
```
Für den nächsten Durchlauf der Schleife :
	
	



```
L hPointer
L 3    // wegen der 3 Byte-Geschichte
+D
T hPointer
 
L hPointer
L #End_Adresse_Daten
<D
SPB Loop
```
Versuch das mal mit in deinen Code zu integrieren ...​


----------



## stevexxx (9 April 2008)

habs schon hinbekommen  war nur ein paar kleine Fehler
zum Thema indirekte Adressierung.. kannte ich mich eigentlich für meine Verhältnisse ziemlich gut aus



L     #iDB_Nr                     
      T     #tDb_Nr                    
      L     #iStartadresse
      T     #sStartadresse
      U     #iStart                     
      FP    #sm1                        
      SPBN  exit

      AUF   DB [#tDb_Nr]                //Aufruf Daten DB
      L     #sStartadresse
M001: LAR1  
      SET   
      S     #oSort_done
      L     #iAnz_Werte
      L     1
      -I    
next: T     #sCount                     //Schleifenzaehler
      L     DBB [AR1,P#0.0]
      L     DBB [AR1,P#1.0]
      <=I   
      SPB   M002
      L     DBB [AR1,P#0.0]
      T     #tTemp
      L     DBB [AR1,P#1.0]
      T     DBB [AR1,P#0.0]
      L     #tTemp
      T     DBB [AR1,P#1.0]
      SET   
      R     #oSort_done
      SPB   M002
M002: TAR1  
      L     8
      +D    
      LAR1  
      L     #sCount
      LOOP  next
      UN    #oSort_done
      SPB   M001
      BE    
exit: NOP   0

thx für eure Hilfe.....


​


----------



## stevexxx (11 April 2008)

Ok muss doch wieder mit anypointern arbeiten aber nicht zum vergleichen von Blöcken sondern nur zum schieben
 ich soll dabei immer nur das erste Byte vom Block mit dem ertsen BYte vom 2ten Block vergleichen...

irgendjemand eine Idee??

code zum verschieben der Blöcke



```
CALL "BLKMOV" //Vergleichsblock1 Zwischenspeichern
SRCBLK :=#tVergleichsblock1
RET_VAL:=#tRetval
DSTBLK :=#tSaveBlock
 
CALL "BLKMOV" //Vergleichsblock2 in Vergleichsblock1 schieben
SRCBLK :=#tVergleichsblock2
RET_VAL:=#tRetval
DSTBLK :=#tVergleichsblock1
 
CALL "BLKMOV" //gespeicherten Vergleichsblock1 in Vergleiochsblock2 schieben
SRCBLK :=#tSaveBlock
RET_VAL:=#tRetval
DSTBLK :=#tVergleichsblock2
```


----------



## centrox (11 April 2008)

Du schiebst Block1 nach Block2, und Block2 nach Block1??? 

Was willst du eigentlich genau machen? Was vergleichen?

gruß centrox


----------



## stevexxx (11 April 2008)

die beschreibung steht am anfang vom thread... der unterschied ist nur das ich nicht den gesamten block vergleiche und dann verschiebe sondern nur das erste byte im block mit dem ersten byte vom benachbarten Block und dann erst blockweise schiebe....


hier der Code für Byteweise sortierung mit Bubblesort
jedoch soll ich Blöcke vergleichen und entsprechend verschieben


```
L     #iDB_Nr                     //DB Nummer einlesen
      T     #tDb_Nr                     //temp. speichern
      L     #iStartadresse              //Startadresse laden
      T     #sStartadresse              //statisch abspeichern
      L     #iSortierbereich            //Lade Sortierbereich
      T     #ssortierbereich            //statisch abspeichern
      L     P#1.0                       //Lade Bytebereich
      ==I                               //Vergleich ob Sortierbereich in BYTE
      U     #iStart                     //bei Start
      FP    #tsm1                       //pos. Flanke  Sortieren
      SPBN  exit
      AUF   DB [#tDb_Nr]                //Aufruf Daten DB
      L     #sStartadresse              //laden der Anfangsadresse
M001: LAR1  
      SET                               //Setze VKE 1
      S     #oSort_done                 //Setze Sortierung 1 Wert fertig
      L     #iAnz_Werte                 //Anzahl der Werte laden
      L     1                           // -1
      -I    
next: T     #sCount                     //Schleifenzaehler 
      L     DBB [AR1,P#0.0]             //Lade Vergleichsbyte 1
      L     DBB [AR1,P#1.0]             //Lade Vergleichsbyte 2
      <=I                               //Vergleichsyte 1 kleiner gleich Vergleichsbyte 2
      SPB   M002
      L     DBB [AR1,P#0.0]             //Lade Vergleichsbyte 1
      T     #tTemp                      //temp. abspeichern
      L     DBB [AR1,P#1.0]             //Lade Vergleichsbyte 2
      T     DBB [AR1,P#0.0]             //transferiere Wert in Vergleichsbyte 1
      L     #tTemp                      //Lade abgespeichertes Vergleichsbyte 1
      T     DBB [AR1,P#1.0]             //transferiere Wert in Vergleichsbyte 2 
      SET                               //Setze VKE 1
      R     #oSort_done                 //Rücksetze Sortierung 1 Wert fertig
      SPB   M002
M002: TAR1  
      L     P#1.0                       // addieren von 1 BYTE zur Adresse der Vergleichbytes
      +D    
      LAR1  
      L     #sCount                     //Schleifenzaehler laden
      LOOP  next
      UN    #oSort_done                 //Wenn Sortierung fuer 1 Wert nicht fertig
      SPB   M001
exit: NOP   0
```


----------



## centrox (11 April 2008)

AR1 auf erstes Byte Block1,
AR2 auf erstes Byte Block2,

nach einem Vergleichskriterium vergleichen,
dann verschieben / sortieren falls erfüllt oder nicht erfüllt.

Soll es so in etwa funktionieren?


----------



## stevexxx (11 April 2008)

ja soweit so gut... die frage ist wie ich das mit dem Offset der ja variabel sein muss hinbekomme    


zb .

L DBB[Ar1,P#0.0]
LDBB[Ar2,P#4.0]    
<=I


die 4.0  also 4 byte versatz sollte ich über eine Variable einstellen können


----------



## vierlagig (11 April 2008)

stevexxx schrieb:


> ja soweit so gut... die frage ist wie ich das mit dem Offset der ja variabel sein muss hinbekomme
> die 4.0  also 4 byte versatz sollte ich über eine Variable einstellen können



die einfachste möglichkeit die mir dazu einfällt:


```
L     #variable1
      SLD   3
      LAR1  

      L     DBB [AR1,P#0.0]
      T     #vergleichswert1

      L     #variable2
      SLD   3
      LAR1  

      L     DBB [AR1,P#0.0]
      T     #vergleichswert2

      L     #vergleichswert1
      L     #vergleichswert2
      <=I
      ....
```


----------



## stevexxx (11 April 2008)

das klingt gut werd ich gliech mals ausprobiern  aber wieso schiebst du das ganze um 3??

thx


----------



## volker (11 April 2008)

wie der anypointer aussieht ist in der FAQ deutlich beschrieben.
der link dazu ist bereits gefallen.

für das tauschen der blöcke falls mehr als 1 dwort getauscht werden soll.
quellzeiger bauen
zielzeiger bauen

      CALL  SFC   20
       SRCBLK := quellzeiger
       RET_VAL:=
       DSTBLK :=P#DB10.DBX 0.0 BYTE 8

      CALL  SFC   20
       SRCBLK := zielzeiger
       RET_VAL:=
       DSTBLK :=P#DB10.DBX 8.0 BYTE 8

      CALL  SFC   20
       SRCBLK := P#DB10.DBX 8.0 BYTE 8
       RET_VAL:=
       DSTBLK := quellzeiger

      CALL  SFC   20
       SRCBLK := P#DB10.DBX 0.0 BYTE 8
       RET_VAL:=
       DSTBLK := zielzeiger


----------



## stevexxx (11 April 2008)

Any zeiger dazu hab ich mir dazu ja schon gebastelt

das ganze funktioniert mit einmal zwischenspeichern auch  und verkürzt somit das programm

ist wert 1 gößer als wert 2 so wird werd i zwischengespeichert  wert 2 in wert 1 geschoben und der zwischengespeicherte wert in wert 2....


----------



## stevexxx (14 April 2008)

komm mit meinem proggi nicht mehr weiter.... 


bisheriger code

```
L     #iDB_Nr                     //DB Nummer einlesen
      T     #tDb_Nr                     //temp. speichern
      L     #iStartadresse              //Startadresse laden
      T     #sStartadresse              //statisch abspeichern
      L     #iBlockgroesse              //Lade Sortierbereich
      T     #sBlockgroesse              //statisch abspeichern
      L     #iSave_DB                   //Db Nummer Zwischenspeicher einlesen
      T     #sSave_DB                   //statisch abspeichern
      L     #sBlockgroesse              //Blockoffsteberechnung
      L     P#1.0
      *D    
      T     #tBlockoffset
      LAR1  P##tVergleichsblock1
      L     B#16#10                     //10h für s7
      T     LB [AR1,P#0.0]
      L     B#16#2                      //Typ BYTE
      T     LB [AR1,P#1.0]
      L     #sBlockgroesse              //Anzahl (Wiederholungsfaktor)
      T     LW [AR1,P#2.0]
      L     #tDb_Nr                     //Datenbaustein
      T     LW [AR1,P#4.0]
      L     #sStartadresse              //Startadresse des ersten Bytes
      SLD   3                           //Pointer bauen
      T     LD [AR1,P#6.0]              //Ergebnis in  Anypointer eintragen
      L     B#16#84                     //Speicherbereich (hier DB)
      T     LB [AR1,P#6.0]
      LAR1  P##tVergleichsblock2
      L     B#16#10                     //10h für s7
      T     LB [AR1,P#0.0]
      L     B#16#2                      //Typ BYTE
      T     LB [AR1,P#1.0]
      L     #sBlockgroesse              //Anzahl (Wiederholungsfaktor)
      T     LW [AR1,P#2.0]
      L     #tDb_Nr                     //Datenbaustein
      T     LW [AR1,P#4.0]
      L     #tBlockoffset               //Startadresse des ersten Bytes
      T     LD [AR1,P#6.0]              //Ergebnis in  Anypointer eintragen
      L     B#16#84                     //Speicherbereich (hier DB)
      T     LB [AR1,P#6.0]
      LAR1  P##tSaveBlock
      L     B#16#10                     //10h für s7
      T     LB [AR1,P#0.0]
      L     B#16#2                      //Typ BYTE
      T     LB [AR1,P#1.0]
      L     #sBlockgroesse              //Anzahl (Wiederholungsfaktor)
      T     LW [AR1,P#2.0]
      L     #sSave_DB                   //Datenbaustein
      T     LW [AR1,P#4.0]
      L     0                           //Startadresse des ersten Bytes
      T     LD [AR1,P#6.0]              //Ergebnis in  Anypointer eintragen
      L     B#16#84                     //Speicherbereich (DB)
      T     LB [AR1,P#6.0]
 
 
 
      U     #iStart                     //bei Start
      FP    #tsm1                       //pos. Flanke  Sortieren
      SPBN  M001
      AUF   "DB3 Sortierung"            //Aufruf Daten DB
      L     #sStartadresse              //laden der Anfangsadresse
M003: LAR1  
      SET                               //Setze VKE 1
      S     #oSort_done                 //Setze Sortierung 1 Wert fertig
      L     #iAnz_Werte                 //Anzahl der Werte laden
      L     1                           // -1
      -I    
M004: T     #sCount                     //Schleifenzaehler 
      AUF   "DB3 Sortierung"            //Auruf Sortier DB
      L     #sMD1                       //Adresse Vergleichsbyte 1
      T     #tMD1
      SLD   3
      LAR1  
      L     DBB [AR1,P#0.0]
      T     #sVergleichswert1
      L     #tMD2
      SLD   3
      LAR1  
      L     DBB [AR1,P#0.0]
      T     #sVergleichswert2
      L     #sVergleichswert1
      L     #sVergleichswert2
      <=I                               //Vergleichsyte 1 kleiner gleich Vergleichsbyte 2
      SPB   M002
      LAR1  P##tVergleichsblock1
      L     #tMD1                       //Speicherbereich (hier DB)
      T     LD     6                    //Ergebnis in  Anypointer eintragen
      LAR1  P##tVergleichsblock2
      L     #tMD2                       //Speicherbereich (hier DB)
      T     LD     6                    //Ergebnis in  Anypointer eintragen
 
      CALL  "BLKMOV"                    //Vergleichsblock1 zwischenspeichern 
       SRCBLK :=#tVergleichsblock1
       RET_VAL:=#tRetval
       DSTBLK :=#tSaveBlock
      CALL  "BLKMOV"                    //Vergleichsblock2 in Vergleichsblock1 schieben
       SRCBLK :=#tVergleichsblock2
       RET_VAL:=#tRetval
       DSTBLK :=#tVergleichsblock1
      CALL  "BLKMOV"                    //gespeicherten Vergleichsblock1 in Vergleiochsblock2 schieben
       SRCBLK :=#tSaveBlock
       RET_VAL:=#tRetval
       DSTBLK :=#tVergleichsblock2
      SET                               //Setze VKE 1
      R     #oSort_done                 //Rücksetze Sortierung 1 Wert fertig
      SPB   M002
M002: L     #tMD2                       //Vergleichsadresse 2 in Vergleichsadresse 1 transferieren
      T     #tMD1
      T     #sMD1
      L     #tMD2
      L     #sBlockoffset               //  addieren des Blockoffsets zur Adresse des Vergleichsblock2
      +D    
      T     #tMD2
      T     #sMD2
      L     #sCount                     //Schleifenzaehler laden
      LOOP  M004
      UN    #oSort_done                 //Wenn Sortierung fuer 1 Wert nicht fertig
      SPB   M003
M001: NOP   0
```


----------



## Larry Laffer (14 April 2008)

... was hat das mit dem ursprünglich geschilderten Problem zu tun ...?


----------



## stevexxx (14 April 2008)

mit dem ursprünglichen problem ... ja damit hat es zu tun


also bsb  hab einen speicher mit 10 byte


diese 10 byte teile ich ein in 5 blöcke
von diesen blöcken vergleiche ich jeweils das erste byte auf ihre größe und verschiebe dann mit blockmove die blöcke


----------



## Larry Laffer (15 April 2008)

Ein Block ist 10 Byte groß und davon hast du 10 ...?
Ist das Byte_1 von Block_1 > Byte_1 von Block_2, dann tauscht du die beiden Blöcke ... so richtig verstanden ...?
Wenn ja, dann musst du erst Block_1 in einen Zwischen-Puffer schreiben, dann Block_2 in Block_1 und dann den Zwischenpuffer in Block_2 ...

Gruß
LL


----------



## stevexxx (15 April 2008)

der speicher is besipielsweise 10 byte groß  und dieser speicher wird besipielsweise in 5 Blöcke a 2 byte eingeteilt  der rest stimmt was du erzählt hast...  


das mitn zwischenspeichern ist ja in meinem programm schon realisiert nur bekomm ich dauern einen Bereichslängenfehler beim lesen beim 2 durchgang... erste tauschdurchgang klappt ja noch


vl siehst du dir ja mal kurz meinen code an   lg stefan


----------



## Larry Laffer (15 April 2008)

Ich habe mir den Code schon angesehen und bin da auf den ersten Blick nicht durchgestiegen. Liegt aber vielleicht auch daran, dass ich meinen Schädel in Augenblick auch mit eine Menge anderem Zeug voll habe ...

Aber grundsätzlich (wie wir das weiter vorne schon behandelt haben) :
Das Arbeiten mit ANY-Pointern und dem FC "Block-Move" macht nur dann Sinn, wenn es sich dabei um große Datenblöcke handelt. 2  bis 4 Byte sind in diesem Sinne kein großer Datenblock. Dein Programm benötigt hier mehr Zeit zum Erstellen und Zerlegen des ANY-Pointers als für den eigentlichen Lade-Transfer-Vorgang. Ich verstehe also nicht, warum du wieder dazu übergehst ...

Weiterhin : Was ist der Inhalt von "#iBlockgroesse" ?

Vielleicht solltest du dein diesbezügliches Konzept noch einmal überdenken ..

Gruß
LL


----------



## stevexxx (15 April 2008)

#iBlockgroesse  = die Anzahl der Bytes pro Block

im meinem Bsb ist die Blockgroesse 2 >>> sprich der Block besteht aus 2 Byte.
Der Speicher welcher in meinem Beispiel 10 Byte groß ist wird also in 5 Blöcke a 2 Byte eingeteilt. Da mein Programm variabel gestaltet werden soll muss ich Blockmove verwenden da auch größere Blöcke verschoben werden sollen.
Beim sortieren der Blöcke in meinem DB schau ich mir immer nur das erste Byte im Block an und tausche anhand der größe (Wert) die einzelnen Blocke miteinander bis sie der Größe nach sortiert sind. (Bubblesort)


lg stefan


----------



## Larry Laffer (15 April 2008)

... dann schreib doch noch mal, was du in "iStartAdresse" als Werte stehen hast ...
Bitte bedenken, so, wie du ihn einsetzt, muss dort ein Pointerwert drin stehen ... Falls nicht, dann ist das der Fehler ...

Gruß
LL


----------



## volker (15 April 2008)

irgendwie find ich den code total wirr. hab auch keine lust mir da jetzt lange gedanken drum zu machen. irgendwie fehlt mir da das bilden des zeigers innerhalb der schleife.

mal in worten:

vorbelegen:
schleifenzähler = 1
bilde zeiger_zwspeicher

anfang:
startadresse berechnen (abhängig vom schleifenzähler und blockgrösse)
bilde zeiger_block1 (startadresse)
bilde zeiger_block2 (startadresse + blockgrösse)
byte der blöcke vergleichen.
wenn byte_block1 > byte_block2 dann tauschen
sonst weiter

tauschen:
block1 -> zwspeicher
block2 -> block1
zwspeicher -> block2
schleifenzähler auf 1 setzen
zum anfang springen

weiter:
schleifenzähler erhöhen
prüfe schleifenzähler ob schon am ende.
wenn nein springe zum anfang

ende:

das ist jetzt kein bubblesort. bubblesort funktioniert ein wenig anders.
ist zwar schneller aber schwieriger zu programmieren.


----------



## Kai (16 April 2008)

stevexxx schrieb:


> Beim sortieren der Blöcke in meinem DB schau ich mir immer nur das erste Byte im Block an und tausche anhand der größe (Wert) die einzelnen Blocke miteinander bis sie der Größe nach sortiert sind. (Bubblesort)


 
Hallo Stefan,

hier ist ein Programmbeispiel für die Sortierung der Datenblöcke mit Bubblesort.

Die Datenblöcke bestehen jeweils aus 4 Bytes und werden nach der Größe des ersten Byte im Datenblock sortiert.


```
FUNCTION FC 100 : VOID
TITLE =Bubblesort
//14
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : BUBBLE
VERSION : 1.0
 
VAR_INPUT
  DB_NUMMER : INT ; 
  STARTADRESSE : INT ; 
  BLOCKGROESSE : INT ; 
  BLOCKANZAHL : INT ; 
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ; 
  AR1_REGISTER : DWORD ; 
  DATENBLOCK_1 : ANY ; 
  DATENBLOCK_2 : ANY ; 
  SPEICHERBLOCK : ANY ; 
  BEREICHSZEIGER_1 : DWORD ; 
  BEREICHSZEIGER_2 : DWORD ; 
  OFFSET : DWORD ; 
  DB_NUMMER_TEMP : WORD ; 
  SCHLEIFE_1 : INT ; 
  SCHLEIFE_2 : INT ; 
  WERT_1 : INT ; 
  WERT_2 : INT ; 
  RETVAL : INT ; 
END_VAR
BEGIN
NETWORK
TITLE =Register sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER;
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
NETWORK
TITLE =Datenblock 1 (ANY)
 
      L     P##DATENBLOCK_1; // Datenblock 1 (ANY)
      LAR1  ; 
 
      L     B#16#10; // Syntax-ID
      T     B [AR1,P#0.0]; 
 
      L     2; // Datentyp
      T     B [AR1,P#1.0]; 
 
      L     #BLOCKGROESSE; // Anzahl
      T     W [AR1,P#2.0]; 
 
      L     #DB_NUMMER; // DB-Nummer
      T     W [AR1,P#4.0]; 
 
      L     #STARTADRESSE; // Bereichszeiger 1
      ITD   ; 
      SLD   3; 
      T     D [AR1,P#6.0]; 
 
      L     B#16#84; // Operandenbereich
      T     B [AR1,P#6.0]; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger 1
      T     #BEREICHSZEIGER_1; 
 
NETWORK
TITLE =Datenblock 2 (ANY)
 
      L     P##DATENBLOCK_2; // Datenblock 2 (ANY)
      LAR1  ; 
 
      L     B#16#10; // Syntax-ID
      T     B [AR1,P#0.0]; 
 
      L     2; // Datentyp
      T     B [AR1,P#1.0]; 
 
      L     #BLOCKGROESSE; // Anzahl
      T     W [AR1,P#2.0]; 
 
      L     #DB_NUMMER; // DB-Nummer
      T     W [AR1,P#4.0]; 
 
      L     #STARTADRESSE; // Bereichszeiger 2
      L     #BLOCKGROESSE; 
      +I    ; 
      ITD   ; 
      SLD   3; 
      T     D [AR1,P#6.0];
 
      L     B#16#84; // Operandenbereich
      T     B [AR1,P#6.0]; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger 2   
      T     #BEREICHSZEIGER_2; 
 
NETWORK
TITLE =Speicherblock (ANY)
 
      L     P##SPEICHERBLOCK; // Speicherblock (ANY) 
      LAR1  ; 
 
      L     B#16#10; // Syntax-ID
      T     B [AR1,P#0.0]; 
 
      L     2; // Datentyp
      T     B [AR1,P#1.0]; 
 
      L     #BLOCKGROESSE; // Anzahl
      T     W [AR1,P#2.0]; 
 
      L     #DB_NUMMER; // DB-Nummer
      T     W [AR1,P#4.0]; 
 
      L     #BLOCKGROESSE; // Bereichszeiger
      L     #BLOCKANZAHL; 
      *I    ; 
      L     #STARTADRESSE; 
      +I    ; 
      ITD   ; 
      SLD   3; 
      T     D [AR1,P#6.0]; 
 
      L     B#16#84; // Operandenbereich
      T     B [AR1,P#6.0]; 
 
NETWORK
TITLE =Offset (Bereichszeiger)
 
      L     #BLOCKGROESSE; 
      ITD   ; 
      SLD   3; 
      T     #OFFSET; 
 
NETWORK
TITLE =Bubblesort 
 
      L     #DB_NUMMER; // DB-Nummer
      T     #DB_NUMMER_TEMP; 
 
      AUF   DB [#DB_NUMMER_TEMP]; 
 
 
      L     #BLOCKANZAHL; 
      L     1; 
      -I    ; 
M01:  T     #SCHLEIFE_1; 
 
 
      L     P##DATENBLOCK_1; // Datenblock 1 (ANY)
      LAR1  ; 
 
      L     #BEREICHSZEIGER_1; // Bereichszeiger 1
      T     D [AR1,P#6.0]; 
 
 
      L     P##DATENBLOCK_2; // Datenblock 2 (ANY)
      LAR1  ; 
 
      L     #BEREICHSZEIGER_2; // Bereichszeiger 2
      T     D [AR1,P#6.0]; 
 
 
      L     #SCHLEIFE_1; 
M02:  T     #SCHLEIFE_2; 
 
 
      L     P##DATENBLOCK_1; // Datenblock 1 (ANY)
      LAR1  ; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger
      LAR1  ; 
 
      L     B [AR1,P#0.0]; // Wert 1
      T     #WERT_1; 
 
 
      L     P##DATENBLOCK_2; // Datenblock 2 (ANY)
      LAR1  ; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger
      LAR1  ; 
 
      L     B [AR1,P#0.0]; // Wert 2
      T     #WERT_2; 
 
 
      L     #WERT_2; // Wert 2
      L     #WERT_1; // Wert 1    
      >I    ; 
      SPBN  M03; 
 
NETWORK
TITLE =Bubblesort
 
      CALL SFC   20 (
           SRCBLK                   := #DATENBLOCK_1,
           RET_VAL                  := #RETVAL,
           DSTBLK                   := #SPEICHERBLOCK);
      NOP   0; 
 
NETWORK
TITLE =Bubblesort
 
      CALL SFC   20 (
           SRCBLK                   := #DATENBLOCK_2,
           RET_VAL                  := #RETVAL,
           DSTBLK                   := #DATENBLOCK_1);
      NOP   0; 
 
NETWORK
TITLE =Bubblesort
 
      CALL SFC   20 (
           SRCBLK                   := #SPEICHERBLOCK,
           RET_VAL                  := #RETVAL,
           DSTBLK                   := #DATENBLOCK_2);
      NOP   0; 
 
NETWORK
TITLE =Bubblesort 
 
M03:  L     P##DATENBLOCK_1; // Datenblock 1 (ANY)
      LAR1  ; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger
      L     #OFFSET; // Offset
      +D    ; 
      T     D [AR1,P#6.0]; 
 
 
      L     P##DATENBLOCK_2; // Datenblock 2 (ANY)
      LAR1  ; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger
      L     #OFFSET; // Offset
      +D    ; 
      T     D [AR1,P#6.0]; 
 
 
      L     #SCHLEIFE_2; 
      LOOP  M02; 
 
      L     #SCHLEIFE_1; 
      LOOP  M01; 
 
NETWORK
TITLE =Register wiederherstellen
 
      AUF   DB [#DB_REGISTER]; // DB-Register
 
      LAR1  #AR1_REGISTER; // AR1-Register
 
END_FUNCTION
```
 
Gruß Kai


----------



## Kai (16 April 2008)

Und hier ist noch ein Bild aus der Simulation mit PLCSIM.

Gruß Kai


----------



## stevexxx (16 April 2008)

das nenne ich Einsatz    10000X danke


----------



## volker (16 April 2008)

ja so ist der kai nun mal. :s1:
der prasentiert immer wieder gern fertige lösungen. (evtl ist er ja auch _danke_ süchtig  )

die meisten die dir in dem thread geantwortet haben hätten dir den code liefern können.
ob das aber der sinn der sache ist, lasse ich mal dahingestellt.
	

	
	
		
		

		
			




du solltest verstehen was du da programmierst und nicht einfach irgendeinen code übernehmen.
beim nächsten problem fängt das gleiche spiel hier wieder von vorne an.


----------



## Kai (16 April 2008)

volker schrieb:


> ob das aber der sinn der sache ist, lasse ich mal dahingestellt.
> du solltest verstehen was du da programmierst und nicht einfach irgendeinen code übernehmen.
> beim nächsten problem fängt das gleiche spiel hier wieder von vorne an.


 
Meine Meinung zu dem Thema kannst Du hier nachlesen:

http://www.sps-forum.de/showpost.php?p=128703&postcount=14

http://www.sps-forum.de/showpost.php?p=128714&postcount=22

Gruß Kai


----------



## Kai (16 April 2008)

Ich habe mein Programmbeispiel für die Sortierung der Datenblöcke mit Bubblesort noch einmal etwas überarbeitet.

Hier ist eine leicht verbesserte Programmversion.


```
FUNCTION FC 100 : VOID
TITLE =Bubblesort
//14
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : BUBBLE
VERSION : 1.0
 
VAR_INPUT
  DB_NUMMER : INT ; 
  STARTADRESSE : INT ; 
  BLOCKGROESSE : INT ; 
  BLOCKANZAHL : INT ; 
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ; 
  AR1_REGISTER : DWORD ; 
  DATENBLOCK_1 : ANY ; 
  DATENBLOCK_2 : ANY ; 
  SPEICHERBLOCK : ANY ; 
  DB_NUMMER_TEMP : WORD ; 
  BEREICHSZEIGER_1 : DWORD ; 
  BEREICHSZEIGER_2 : DWORD ; 
  OFFSET : DWORD ; 
  SCHLEIFE_1 : INT ; 
  SCHLEIFE_2 : INT ; 
  WERT_1 : INT ; 
  WERT_2 : INT ; 
  RETVAL : INT ; 
END_VAR
BEGIN
NETWORK
TITLE =Register sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
NETWORK
TITLE =Datenblock 1 (ANY)
 
      L     P##DATENBLOCK_1; // Datenblock 1 (ANY)
      LAR1  ; 
 
      L     B#16#10; // Syntax-ID
      T     B [AR1,P#0.0]; 
 
      L     2; // Datentyp
      T     B [AR1,P#1.0]; 
 
      L     #BLOCKGROESSE; // Anzahl
      T     W [AR1,P#2.0]; 
 
      L     #DB_NUMMER; // DB-Nummer
      T     W [AR1,P#4.0]; 
 
      L     #STARTADRESSE; // Bereichszeiger
      ITD   ; 
      SLD   3; 
      T     D [AR1,P#6.0]; 
 
      L     B#16#84; // Operandenbereich
      T     B [AR1,P#6.0]; 
 
NETWORK
TITLE =Datenblock 2 (ANY)
 
      L     P##DATENBLOCK_2; // Datenblock 2 (ANY)
      LAR1  ; 
 
      L     B#16#10; // Syntax-ID
      T     B [AR1,P#0.0]; 
 
      L     2; // Datentyp
      T     B [AR1,P#1.0]; 
 
      L     #BLOCKGROESSE; // Anzahl
      T     W [AR1,P#2.0]; 
 
      L     #DB_NUMMER; // DB-Nummer
      T     W [AR1,P#4.0]; 
 
      L     #STARTADRESSE; // Bereichszeiger
      L     #BLOCKGROESSE; 
      +I    ; 
      ITD   ; 
      SLD   3; 
      T     D [AR1,P#6.0]; 
 
      L     B#16#84; // Operandenbereich
      T     B [AR1,P#6.0]; 
 
NETWORK
TITLE =Speicherblock (ANY)
 
      L     P##SPEICHERBLOCK; // Speicherblock (ANY) 
      LAR1  ; 
 
      L     B#16#10; // Syntax-ID
      T     B [AR1,P#0.0]; 
 
      L     2; // Datentyp
      T     B [AR1,P#1.0]; 
 
      L     #BLOCKGROESSE; // Anzahl
      T     W [AR1,P#2.0]; 
 
      L     #DB_NUMMER; // DB-Nummer
      T     W [AR1,P#4.0]; 
 
      L     #BLOCKGROESSE; // Bereichszeiger
      L     #BLOCKANZAHL; 
      *I    ; 
      L     #STARTADRESSE; 
      +I    ; 
      ITD   ; 
      SLD   3; 
      T     D [AR1,P#6.0]; 
 
      L     B#16#84; // Operandenbereich
      T     B [AR1,P#6.0]; 
 
NETWORK
TITLE =Bubblesort 
 
      L     #DB_NUMMER; 
      T     #DB_NUMMER_TEMP; 
 
      AUF   DB [#DB_NUMMER_TEMP]; 
 
 
      L     P##DATENBLOCK_1; // Datenblock 1 (ANY)
      LAR1  ; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger 1
      T     #BEREICHSZEIGER_1; 
 
 
      L     P##DATENBLOCK_2; // Datenblock 2 (ANY)
      LAR1  ; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger 2
      T     #BEREICHSZEIGER_2; 
 
 
      L     #BLOCKGROESSE; // Offset
      ITD   ; 
      SLD   3; 
      T     #OFFSET; 
 
 
      L     #BLOCKANZAHL; 
      L     1; 
      -I    ; 
M01:  T     #SCHLEIFE_1; 
 
 
      L     P##DATENBLOCK_1; // Datenblock 1 (ANY)
      LAR1  ; 
 
      L     #BEREICHSZEIGER_1; // Bereichszeiger 1
      T     D [AR1,P#6.0]; 
 
 
      L     P##DATENBLOCK_2; // Datenblock 2 (ANY)
      LAR1  ; 
 
      L     #BEREICHSZEIGER_2; // Bereichszeiger 2
      T     D [AR1,P#6.0]; 
 
 
      L     #SCHLEIFE_1; 
M02:  T     #SCHLEIFE_2; 
 
 
      L     P##DATENBLOCK_1; // Datenblock 1 (ANY)
      LAR1  ; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger
      LAR1  ; 
 
      L     B [AR1,P#0.0]; // Wert 1
      T     #WERT_1; 
 
 
      L     P##DATENBLOCK_2; // Datenblock 2 (ANY)
      LAR1  ; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger
      LAR1  ; 
 
      L     B [AR1,P#0.0]; // Wert 2
      T     #WERT_2; 
 
 
      L     #WERT_2; // Wert 2
      L     #WERT_1; // Wert 1    
      >I    ; 
      SPBN  M03; 
 
NETWORK
TITLE =Bubblesort
 
      CALL SFC   20 (
           SRCBLK                   := #DATENBLOCK_1,
           RET_VAL                  := #RETVAL,
           DSTBLK                   := #SPEICHERBLOCK);
      NOP   0; 
 
NETWORK
TITLE =Bubblesort
 
      CALL SFC   20 (
           SRCBLK                   := #DATENBLOCK_2,
           RET_VAL                  := #RETVAL,
           DSTBLK                   := #DATENBLOCK_1);
      NOP   0; 
 
NETWORK
TITLE =Bubblesort
 
      CALL SFC   20 (
           SRCBLK                   := #SPEICHERBLOCK,
           RET_VAL                  := #RETVAL,
           DSTBLK                   := #DATENBLOCK_2);
      NOP   0; 
 
NETWORK
TITLE =Bubblesort 
 
M03:  L     P##DATENBLOCK_1; // Datenblock 1 (ANY)
      LAR1  ; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger
      L     #OFFSET; // Offset
      +D    ; 
      T     D [AR1,P#6.0]; 
 
 
      L     P##DATENBLOCK_2; // Datenblock 2 (ANY)
      LAR1  ; 
 
      L     D [AR1,P#6.0]; // Bereichszeiger
      L     #OFFSET; // Offset
      +D    ; 
      T     D [AR1,P#6.0]; 
 
 
      L     #SCHLEIFE_2; 
      LOOP  M02; 
 
      L     #SCHLEIFE_1; 
      LOOP  M01; 
 
NETWORK
TITLE =Register wiederherstellen
 
      AUF   DB [#DB_REGISTER]; // DB-Register
 
      LAR1  #AR1_REGISTER; // AR1-Register
 
END_FUNCTION
```
 
Gruß Kai


----------



## volker (16 April 2008)

Kai schrieb:


> Meine Meinung zu dem Thema kannst Du hier nachlesen:


ich kenne deine meinung dazu

nichts desto trotz finde ich die nicht gut.
aber das ist ansichtssache.
ist aber auch nicht thema dieses threads.


----------



## stevexxx (17 April 2008)

nochmal danke fürs tolle Programm !


----------



## RainerP (15 November 2008)

*Sortieren auch für DINT-Werte?*

Bin beim stöbern auf die Sortierfunktion gestossen und hab ein wenig damit herumgespielt. Ich würde gern ca 50 -100 Datenblöcke, bestehend aus je 2 Dint-Werten sortieren. Das ist mir jedoch nicht gelungen, an welchen Stellen müsste ich hier drehen?
Ich habe die beiden DB-s angepasst und die Paramerierung des FC-100eingestellt auf Blockgrösse 2 und Blockanzahl 10 für den Anfang.
Was fehlt da noch?


----------



## Larry Laffer (15 November 2008)

Hallo Rainer,
die Blockgröße im obigen Fall ist in Byte angegeben. 1 DINT hat eine Größe von 4 Byte (bzw. 2 DINT dann sogar 8 Byte). Hast du das berücksichtigt ?
Darüber hinaus kannst du DINT-Werte allerdings auch direkt vergleichen und sortieren (ohne dabei den Block-Move zum Einsatz zu bringen). Das erspart dir den Einsatz und das Aufbauen eines ANY-Pointers ...

Wenn du Hlfe zu einem von dir verfassten Baustein haben möchtest, dann kann es oft auch ganz praktisch sein, den Baustein hier einzustellen ... 

Gruß
LL


----------



## Kai (15 November 2008)

RainerP schrieb:


> Bin beim stöbern auf die Sortierfunktion gestossen und hab ein wenig damit herumgespielt. Ich würde gern ca 50 -100 Datenblöcke, bestehend aus je 2 Dint-Werten sortieren.


 
Hier ist noch einmal ein neues Programmbeispiel für die Sortierung von Datenblöcken mit Bubblesort.

Die Datenblöcke bestehen aus zwei Werten im Datenformat DINT und werden nach der Größe des ersten Wertes im Datenblock sortiert.

Der Datenbaustein, die Startadresse sowie die Anzahl der Datenblöcke ist variabel.


```
FUNCTION FC 100 : VOID
TITLE =Bubblesort
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : BUBBLE
VERSION : 1.0
 
VAR_INPUT
  DATENBAUSTEIN : BLOCK_DB ; 
  STARTADRESSE : INT ; 
  BLOCKANZAHL : INT ; 
END_VAR
VAR_TEMP
  DB_REGISTER : WORD ; 
  AR1_REGISTER : DWORD ; 
  BEREICHSZEIGER : DWORD ; 
  SCHLEIFE_1 : INT ; 
  SCHLEIFE_2 : INT ; 
END_VAR
BEGIN
NETWORK
TITLE =Register sichern
 
      L     DBNO; // DB-Register
      T     #DB_REGISTER; 
 
      TAR1  #AR1_REGISTER; // AR1-Register
 
NETWORK
TITLE =Bubblesort
 
      AUF   #DATENBAUSTEIN; // Datenbaustein
 
      L     #STARTADRESSE; // Startadresse
      ITD   ; 
      SLD   3; 
      T     #BEREICHSZEIGER; // Bereichszeiger
 
      L     #BLOCKANZAHL; // Blockanzahl
      L     1; 
      -I    ; 
M01:  T     #SCHLEIFE_1; 
 
      L     #BEREICHSZEIGER; // Bereichszeiger
      LAR1  ; 
 
      L     #SCHLEIFE_1; 
M02:  T     #SCHLEIFE_2; 
 
      L     DBD [AR1,P#8.0]; // Wert 2-1
      L     DBD [AR1,P#0.0]; // Wert 1-1
      >D    ; 
      SPBN  M03; 
 
      L     DBD [AR1,P#0.0]; // Wert 1-1
      L     DBD [AR1,P#8.0]; // Wert 2-1
      T     DBD [AR1,P#0.0]; // Wert 2-1 => Wert 1-1
      TAK   ; 
      T     DBD [AR1,P#8.0]; // Wert 1-1 => Wert 2-1
 
      L     DBD [AR1,P#4.0]; // Wert 1-2
      L     DBD [AR1,P#12.0]; // Wert 2-2
      T     DBD [AR1,P#4.0]; // Wert 2-2 => Wert 1-2
      TAK   ; 
      T     DBD [AR1,P#12.0]; // Wert 1-2 => Wert 2-2
 
M03:  L     P#8.0; 
      +AR1  ; 
 
      L     #SCHLEIFE_2; 
      LOOP  M02; 
 
      L     #SCHLEIFE_1; 
      LOOP  M01; 
 
NETWORK
TITLE =Register wiederherstellen
 
      AUF   DB [#DB_REGISTER]; 
 
      LAR1  #AR1_REGISTER; 
 
END_FUNCTION
```
 
Gruß Kai


----------



## Kai (15 November 2008)

Und noch eine Bild aus der Simulation mit PLCSIM.

Gruß Kai


----------



## Kai (15 November 2008)

Bubblesort benötigt zum Sortieren einer Datenfolge der Länge n folgende Anzahl von Vergleichen: 


```
n * (n - 1)
Vergleiche = (n - 1) + (n - 2) + ... + 1 = -----------
                                                2
```
 
Bei einer Datenfolge von n = 100 Datenblöcken benötigt Bubblesort also die folgende Anzahl von Durchläufen und Vergleichen:


```
Durchläufe = (n - 1) = (100 - 1) = 99
```
 

```
n * (n - 1)   100 * (100 - 1)
Vergleiche = ----------- = --------------- = 4950
                  2               2
```
 
Gruß Kai


----------



## RainerP (16 November 2008)

*Danke, so gehts!*

Danke, so funktioniert auch mein Beispiel. Bin zwar noch nicht wirklich dahintergestiegen warum... Wird aber noch.
Allerdings hab ich die Funktion aus den PDFs entnommen, in der Zip-Datei ist ein anderer Baustein.
Die Zeit ist hier nicht wirklich relevant, es wird durch das Sortieren wesentlich mehr Zeit eingespart als verbraucht.


----------



## Kai (16 November 2008)

RainerP schrieb:


> Allerdings hab ich die Funktion aus den PDFs entnommen, in der Zip-Datei ist ein anderer Baustein.


 
Das verstehe ich jetzt nicht. 

Ich habe gerade noch einmal die ZIP-Datei kontrolliert und die STEP 7 Bausteine stimmen mit den PDF-Files überein.

http://www.sps-forum.de/showpost.php?p=166905&postcount=56

Gruß Kai


----------



## RainerP (16 November 2008)

*Hast wohl recht*

Habs grade nochmal kontrolliert, Du hast recht. Die Bausteine stimmen.
Werd sie wohl beim Downloaden durcheinander gewürfelt haben.


----------



## RainerP (17 November 2008)

*Andere Sortierreihenfolge?*

Muss nochmal nachhaken: Wenn ich die Sortierreihenfolge umdrehen will, wie müsste ich da vorgehen? Ich bräuchte den 1.Wert der größer ist als 0 an oberster Position.


----------



## Steve81 (17 November 2008)

RainerP schrieb:


> Muss nochmal nachhaken: Wenn ich die Sortierreihenfolge umdrehen will, wie müsste ich da vorgehen? Ich bräuchte den 1.Wert der größer ist als 0 an oberster Position.


 
Jetzt mal ohne groß darüber nachzudenken würde ich sagen da wo auf >D verglichen wird auf <D vergleichen.


----------



## RainerP (17 November 2008)

Das bringt mir den grössten Wert an unterste Position, und wenn einige Nullwerte dabei sind habe ich die an den ersten Positionen


----------



## Steve81 (18 November 2008)

RainerP schrieb:


> Das bringt mir den grössten Wert an unterste Position, und wenn einige Nullwerte dabei sind habe ich die an den ersten Positionen


 
Das ist richtig, du kannst aber auch vor der Überprüfung auf <D die Werte auf 0 prüfen und in diesem Fall sie wie sehr große Werte (den maximal erreichbaren) behandeln und so die Tauschfunktion überspringen. Dann sollten zum Schluss die 0 Werte an den letzten Positionen stehen.

Noch eine Möglichkeit wäre, auf 0 zu prüfen und wenn ja dort wo eine 0 ist den maximal möglichen Wert (+2147483647) hin zu transferieren.


----------



## RainerP (18 November 2008)

*nicht ganz richtig*

Stimmt nicht ganz, hat mich aber auf den (hoffentlich?) richtigen Weg gebracht: Wenn der "Wert 1" 0 ist, muss ich auf jedenfall tauschen.
Tauschen muss ich überspringen, wenn der "Wert 2" 0 ist.
Habs mal überarbeitet und probiert, so scheints zu gehen:



```
Netzwerk 1: Register sichern
 
      L     DBNO                        // DB-Register
      T     #DB_REGISTER
      TAR1  #AR1_REGISTER               // AR1-Register
 
 
Netzwerk 2: Bubblesort
 
      AUF   #DATENBAUSTEIN              // Datenbaustein
      L     #STARTADRESSE               // Startadresse
      ITD   
      SLD   3
      T     #BEREICHSZEIGER             // Bereichszeiger
      L     #BLOCKANZAHL                // Blockanzahl
      L     1
      -I    
M01:  T     #SCHLEIFE_1
      L     #BEREICHSZEIGER             // Bereichszeiger
      LAR1  
      L     #SCHLEIFE_1
M02:  T     #SCHLEIFE_2
 
      L     0
      L     DBD [AR1,P#0.0]             // Wert 1-1
      ==D   
      SPB   M04
      L     0
      L     DBD [AR1,P#8.0]             // Wert 2-1
      ==D   
      SPB   M03
      L     DBD [AR1,P#0.0]             // Wert 1-1
      <D    
      SPBN  M03
M04:  L     DBD [AR1,P#0.0]             // Wert 1-1
      L     DBD [AR1,P#8.0]             // Wert 2-1
      T     DBD [AR1,P#0.0]             // Wert 2-1 => Wert 1-1
      TAK   
      T     DBD [AR1,P#8.0]             // Wert 1-1 => Wert 2-1
      L     DBD [AR1,P#4.0]             // Wert 1-2
      L     DBD [AR1,P#12.0]            // Wert 2-2
      T     DBD [AR1,P#4.0]             // Wert 2-2 => Wert 1-2
      TAK   
      T     DBD [AR1,P#12.0]            // Wert 1-2 => Wert 2-2
M03:  L     P#8.0
      +AR1  
      L     #SCHLEIFE_2
      LOOP  M02
      L     #SCHLEIFE_1
      LOOP  M01
 
Netzwerk 3:  Register wiederherstellen
 
      AUF   DB [#DB_REGISTER]
      LAR1  #AR1_REGISTER
```
 
Die Bausteine hab ich mal angehängt, Bitte mal prüfen ob ich was übersehen habe.


----------



## Steve81 (18 November 2008)

RainerP schrieb:


> Stimmt nicht ganz, hat mich aber auf den (hoffentlich?) richtigen Weg gebracht: Wenn der "Wert 1" 0 ist, muss ich auf jedenfall tauschen.
> Tauschen muss ich überspringen, wenn der "Wert 2" 0 ist.
> Habs mal überarbeitet und probiert, so scheints zu gehen:


 
Hallo,
ja sorry, dass mit dem Tauschen wenn der "Wert1"(DBD [AR1,P#0.0]) 0 ist stimmt natürlich, sonst bleibt der ja einfach stehen wo er ist (hoffe ich  habe nicht für zu viel Verwirrung gesorgt).
Deine Lösung sieht jetzt aber mal sehr vielversprechend aus. Testen kann ichs im Moment leider nicht.


----------



## RainerP (19 November 2008)

*Fertigmeldung ausgeben*

Mal noch ne Frage:
Hab derzeit noch keine Peripherie ums auszuprobieren und ich denke die Simulation mit PLC-Sim ist hierfür nicht wirklich aussagekräftig.
Wenn ich bei 100 Datenblöcken ca. 4950 Durchläufe brauch, wäre eine Fertigmeldung, die mir anzeigt "Sortieren abgeschlossen" hilfreich.
Reicht es hierfür aus, hinter der letzen Schleife ein Bit zu setzen?
Zweite Frage:
Wie wirken sich die 4950 Durchläufe auf die Zyklus-Zeit aus?
Wenn ich das richtig verstehe werden die 4950 Durchläufe in einem Zyklus gemacht oder seh ich das falsch?


----------



## Steve81 (19 November 2008)

Ein Bit nach dem Beenden der letzten Schleife zu setzen sollte ausreichen (z.B. in NW3). Du musst es aber auch irgendwann wieder zurücksetzen. 

Die Auswirkung auf die Zykluszeit hängt von deiner CPU ab, sollte aber nicht dramatisch sein falls dich nicht schon in einem kritischen Bereich bewegst.

Die Sortierung (also die 4950 Durchläufe) wird in einem Zyklus abgearbeitet.


----------



## RainerP (19 November 2008)

Ich stell mir das so vor, das ich dieses Bit als "in-Out" deklariere und die Schleife nur bearbeite wenn das Bit 0 ist. Dann kann ich das Bit von Aussen zurücksetzen und damit die Sortierung anstossen.
CPU wird ne 319, die sollte damit keine Probleme haben.
Problematisch wäre das sicher nur wenn die 4950 jedesmal einen Zyklus bräuchten, das wären bei einer Zyklus-Zeit von 5 ms knapp 25 sek.....


----------



## Steve81 (19 November 2008)

RainerP schrieb:


> Ich stell mir das so vor, das ich dieses Bit als "in-Out" deklariere und die Schleife nur bearbeite wenn das Bit 0 ist. Dann kann ich das Bit von Aussen zurücksetzen und damit die Sortierung anstossen.
> CPU wird ne 319, die sollte damit keine Probleme haben.
> Problematisch wäre das sicher nur wenn die 4950 jedesmal einen Zyklus bräuchten, das wären bei einer Zyklus-Zeit von 5 ms knapp 25 sek.....


 
Das mit dem Bit und das es mit ner 319er keine Probleme gibt ist soweit ok.
Aber mit der Berechnung deiner Zykluszeit komme ich nicht ganz mit. Wenn du eine Zykluszeit von 5ms hast, wird der Baustein innerhalb dieser 5ms bearbeitet. Er ist ja ein Teil deines Zyklus und benutzt nicht einen Zyklus oder habe ich da jetzt was nicht ganz verstanden?


----------



## RainerP (19 November 2008)

Hab mich ein wenig verdrückt ausgekehrt:
Wäre nur dann ein Problem wenn ich für die 4950 Durchläufe auch 4950 
Zyklen bräuchte, aber das ist ja nicht der Fall.


----------

