# Addierer



## _Praktikant_ (14 August 2007)

Hallo erstmal an alle,

ich habe vor kurzem mein Praktikum in einer SPS-Abteilung begonnen und
meine Vorkenntnisse sind eher gering :???:
Zur Einübung soll ich 2 (32bit) Dualzahlen addieren, aber ohne die vorhandene Add.funktion.
Die bisherigen Beiträge zur indirekten Adressierung haben mir auch noch nicht die Erleuchtung gebracht (ich hoffe hier auf Hilfe zur Aufgabe).
Mein vorläufiger Ansatz (für die Schleife):


```
// Laden der 
                  beiden Doppelwörter      

                  L 32
          loop:   T #Schleifenzähler
                  
                  X L 0.0              //summand1
                  X L 2.0              //summand2
                  X #übertrag
                  = L 4.0              //ergebnis



                  L #schleifenzähler
                  LOOP loop

                  //Ergebnis speichern
```

Mir gehts jetzt egtl. auch nur um die Schleife und v.a. um die Verarbeitung/
Verknüpfung des Übertrags (mit ind. Adr.), hab noch keine laufende Lösung?!
Für Tipps/Hilfen wär ich sehr dankbar
Gruß _Praktikant_


----------



## gravieren (15 August 2007)

Hi



> Zur Einübung soll ich 2 (32bit) Dualzahlen addieren, aber ohne die vorhandene Add.funktion.


 
Würde sagen:

Wandle eine Zahl in eine Negative Zahl um  ( Zahl *-1)

Subtrahiere dann die Beiden Zahlen.

Reihenfolge der Subtraktion beachten  !


Zahl =  Zahl_1  +  Zahl_2

identisch mit 

Zahl = Zahl_1 - (Zahl_2  *-1)


Wo ist das Problem.


Irgenwie DOOF die Aufgabenstellung    

Sollst du Progen oder Grundlagen Mathematik machen


----------



## Ralle (15 August 2007)

Na prima, da haben sie dir ja gleich ne tolle Aufgabe gestellt, ob die wissen das da mindestens eine Stolperfalle lauert?

Also deine Schleife ist schon mal im Ansatz richtig. 
Denk daran, daß deine Schleife rückwärts zählt. Wenn du also indirekt
adressieren willst, mußt du dir noch eine Variable haben die hochläuft.
Z.Bsp.


```
L 32
L #Schleifenzaehler
-I
T #Zaehlvar
```
Da ist dann natürlich eine echte Addition drin, aber das ist ja hoffentlich nicht verboten.

Summand_1, Summand_2 und das Ergebnis legst du im Tempbereich des Bausteins *hintereinander* als DINT an.
Am Anfang, vor der Schleife werden Summand_1, Summand_2 in diese Temp-Var hineinkopiert. Das Ergebnis auf 0.
Innerhalb der Schleife kannst du dann wie folgt indirekt zugreifen:


```
L     P##Summand_1_Temp; //die Adresse von Summand_1_Temp wird geladen
      LAR1  ; 

      L     32; 
      L     #Schleifenzaehler; 
      -I    ; 
      +AR1  ; //das bewirkt, daß z.bsp. bei +8, das AR1 um 8 Bit erhöht wird!

//Ergebnisbit berechnen  
      X      [AR1,P#0.0]; //summand1
      X      [AR1,P#4.0]; //summand2
      X     #Uebertrag_Temp; //übertrag
      =      [AR1,P#8.0]; //ergebnis
```
Nach der Schleife, das Ergebnis in die Autput-Variable schreiben.

Ich stell mal bewußt nicht den kompletten FC ein, du sollst ja was lernen. 
Wenn du nicht weiterkommst stelle hier die Fragen, ich helf dir weiter, bis es läuft, danach weißt du hoffentlich auch warum, das läuft. 

Noch ein paar wichtige Links, die solltest du zuerst mal lesen:

http://www.sps-forum.de/showthread.php?t=8887
http://de.wikipedia.org/wiki/XOR
http://de.wikipedia.org/wiki/Dualsystem#Schriftliche_Addition hier vor allem die Ergebnistabelle, wegen der Berechnung des neuen Übertrags !

Zu der schicken Siemens-Stolperfalle kommen wir dann auch noch .


----------



## Ralle (15 August 2007)

gravieren schrieb:


> Hi
> 
> Würde sagen:
> 
> ...



Ich denk mal, er soll das wirklich binär machen.


----------



## gravieren (15 August 2007)

Hi Ralle



> Ich denk mal, er soll das wirklich binär machen.


Warum, ist die Lösung von mir falsch.

In der Frage stand NIX von Schleifen UND Indirekter Adressierung. 


@Ralle


> Da ist dann natürlich eine echte Addition drin, aber das ist ja hoffentlich nicht verboten.


Addition ist Addition.

Verboten  ;-)

Will auch mal Recht haben.  :-(


----------



## Steve81 (15 August 2007)

@gravieren
Deine Lösung ist bestimmt nicht falsch, wird aber wohl das Thema verfehlen.

Also entweder Note 1 für den einfachsten Weg zur Lösung oder Note 6 für Thema verfehlt.

Ich denke schon dass der Lösungsansatz von Ralle schon eher an das hin kommt was der Aufgabensteller haben will!


----------



## Ralle (15 August 2007)

gravieren schrieb:


> Hi Ralle
> 
> 
> Warum, ist die Lösung von mir falsch.
> ...



Gut, gut, hast recht . Falsch hab ich gar nicht behauptet, grins.

Er sprach von indirekter Adressierung, daher kam ich darauf. 
Man kann das Ganze auch komplett zu Fuß machen, und 32 Mal die XOR-Verknüpfungen etc. hintereinander weg schreiben. Das geht bestimmt sogar in KOP/FUP !


----------



## gravieren (15 August 2007)

Hi   Steve81




> Zur Einübung soll ich 2 (32bit) Dualzahlen addieren, aber ohne die vorhandene Add.funktion.


Klare Ansage  




> Ich denke schon dass der Lösungsansatz von Ralle schon eher an das hin kommt was der Aufgabensteller haben will!


Kennt du den Konrad (Aufgabensteller) 
Nebenbei bemerkt.
Bei meinen Progs (Habe schon einige Dutzend geschrieben (810D,840D)
gibt es selten Konstrukte mit mehr als 8 Zeilen.

Habe schon nach 10 Jahren meine Logiken Problemlos noch lesen können.
(Kann jedoch auch an meinen vielen Kommentaren im Prog liegen)
(Werde nach KB-Anweisungen bezahlt, und Kommentare zählen auch dazu  )


----------



## Steve81 (15 August 2007)

gravieren schrieb:


> Kennt du den Konrad (Aufgabensteller)


 
Nein kenne ich nicht. 
Deine lösung finde ich ja an sich auch super, da sie die Aufgabenstellung wie wir sie kennen erfüllt und absolut einfach zu verstehen ist.

@_Praktikant_
Ich denke du solltest dich noch mal zu den Lösungsansätzen äusern, schließlich kannst du am besten abschätzen was der Aufgabensteller von dir will.


----------



## gravieren (15 August 2007)

Hi Steve81



> @_Praktikant_
> Ich denke du solltest dich noch mal zu den Lösungsansätzen äusern, schließlich kannst du am besten abschätzen was der Aufgabensteller von dir will.


Komisch, ich bin bald 20 Jahre Verheiratet und weis NICHT einmal was meine Frau "will"


----------



## Steve81 (15 August 2007)

gravieren schrieb:


> Hi Steve81
> 
> 
> Komisch, ich bin bald 20 Jahre Verheiratet und weis NICHT einmal was meine Frau "will"


 
Ich seit einem! Du hast soeben meine Hoffnung zerstört.


----------



## Kai (15 August 2007)

_Praktikant_ schrieb:


> Zur Einübung soll ich 2 (32bit) Dualzahlen addieren, aber ohne die vorhandene Add.funktion.


 
Folgender Programmcode sollte auch ohne indirekte Adressierung funktionieren.  

Es ist dabei der Wertebereich für DINT-Zahlen von -2.147.483.648 bis 2.147.483.647 zu beachten.


```
L     MD   100                    // Zahl 1
      T     MD   120                    // Zahl 1
 
      L     MD   110                    // Zahl 2
      T     MD   130                    // Zahl 2
 
 
      L     32
M01:  T     MW   200                    // Schleife
 
 
      L     MD   120                    // Zahl 1
      L     MD   130                    // Zahl 2
      XOD   
      T     MD   140                    // Zwischenwert
 
      L     MD   120                    // Zahl 1
      L     MD   130                    // Zahl 2
      UD    
      T     MD   150                    // Überlauf
 
      L     MD   150                    // Überlauf
      SLD   1
      T     MD   150                    // Überlauf
 
 
      L     MD   140                    // Zwischenwert
      T     MD   120                    // Zahl 1
 
      L     MD   150                    // Überlauf
      T     MD   130                    // Zahl 2
 
 
      L     MW   200                    // Schleife
      LOOP  M01
 
 
      L     MD   140                    // Zwischenwert
      L     MD   150                    // Überlauf
      OD    
      T     MD   160                    // Ergebnis
```
 
Gruß Kai


----------



## Ralle (15 August 2007)

Kai schrieb:


> Folgender Programmcode sollte auch ohne indirekte Adressierung funktionieren.









Stöhn, wie wärs denn mit einem Ansatz, statt der kompletten Lösung!


----------



## _Praktikant_ (15 August 2007)

Hallo,
danke erst mal für die schnellen Antworten:s12: 
Also die Aufgabe soll binäre Addition sein, mit Schleife und
ind. Adr.
Werd gleich morgen mit den Tipps von Ralle versuchen in der
aufgabe weiter zu kommen!
Meld mich wieder...
Mfg


----------



## Onkel Dagobert (15 August 2007)

*Tad*

Also, die Aufgabe ist wirklich gut :twisted: .

Indirekte Adressierung, Schleife und Stolperklippen bei der Ermittlung des Übertrags! Eine wirklich besch.. äh gelungene Kombination für eine Übungsaufgabe. Viel Spaß!

Kleiner Tipp: 

Befehl *TAD* ansehen!
ein Übertrag erfolgt, wenn
1. beide bits in den Zahlen "1" sind, ODER
2. ein bit "1" ist UND ein Übertrag ansteht
Gruß, Onkel


----------



## Ralle (15 August 2007)

Onkel Dagobert schrieb:


> Also, die Aufgabe ist wirklich gut :twisted: .
> 
> Indirekte Adressierung, Schleife und Stolperklippen bei der Ermittlung des Übertrags! Eine wirklich besch.. äh gelungene Kombination für eine Übungsaufgabe. Viel Spaß!
> 
> ...



Die Tips sind gut .


----------



## Onkel Dagobert (15 August 2007)

Ralle schrieb:


> Die Tips sind gut .


Na setze noch einen zur ind. Adressierung drauf. Ist nur ein Vorschlag, natürlich geht es auch anders. Ich würde es in einer FC mit AR1 und AR2 adressieren.


```
...
...
      L     32
L001: T     #TEMP_INT
//*** Binärergebnis unter Berücksichtigung des Übertrag
      X      [AR1,P#0.0]
      X      [AR2,P#0.0]
      X     #UEBERTRAG
      =     #EINS                       // Ergebnisbit
 
//*** Übertrag
...
...
...
      =     #UEBERTRAG
 
      U     #EINS
      =      [AR2,P#0.0]                // am Ende Summand in AR2
 
...
...
      +AR1  P#0.1
      +AR2  P#0.1
      L     #TEMP_INT
      LOOP  L001
```
 

Gruß, Onkel


----------



## Ralle (15 August 2007)

@Onkel

nö, brauchste nicht, AR1 reicht vollkommen.


----------



## Onkel Dagobert (15 August 2007)

Ralle schrieb:


> @Onkel
> 
> nö, brauchste nicht, AR1 reicht vollkommen.


Ja ok, ursprünglich wollte ich auf die Bausteinparameter adressieren. Dann ist es mit zwei unabhängigen Zeigern sinnvoll, da die Parameter in unterschiedlichen Datenbereichen liegen könnten. 


Gruß, Onkel


----------



## _Praktikant_ (16 August 2007)

Hallo,

also weil ich grad komplett verwirrt bin und nicht vorwärts komm..
sorry wenn ich blöde fragen stelle ( bin halt totaler anfänger und tue
mir schwer mit der umsetzung in prog.code).
Die links hab ich mir angeschaut und die theorie ist soweit klar:
für den übertrag müsste es 4 möglichkeiten für einen übertrag und 
4 für keinen (je abhängig von den summanden) geben.
Fragen:


> Summand_1, Summand_2 und das Ergebnis legst du im Tempbereich des Bausteins *hintereinander* als DINT an.


Mir wurde am anfang dword gesagt -> beides möglich??


> Am Anfang, vor der Schleife werden Summand_1, Summand_2 in diese Temp-Var hineinkopiert.


Ist hier kopieren von werten aus DB in temp-var gemeint?


> ```
> L     32;
> L     #Schleifenzaehler;
> -I    ;
> ...


 -I => #schleifenzähler - 32 ( Akku1 -Akku2) und szähler ist doch < 32 => neg Wert

Was fehlt denn noch alles bei der schleife von onkel dagobert?
XOR-verknüpfung von s1,s1 und altem übertrag und...?

Wie gesagt sorry, aber fang ganz von vorne an, mfg!


----------



## Ralle (16 August 2007)

_Praktikant_ schrieb:


> Mir wurde am anfang dword gesagt -> beides möglich??



Ja, es ist beides möglich, ich habs mal probiert. Mit DInt ist die Eingabe am Input des FC einfacher, ab DW#16#7FFFFFFF (größte DINT) wird dann so oder so in der Variablentabelle bei Einstellung DEZ immer eine Negative Zahl bei Addition angezeigt. 

DW#16#7FFFFFFF
+
DW#16#00000002
=
DW#16#80000001
--> L#-2147483647 (mit Vorzeichen) (das ist so, weil die DINT "überläuft")
oder
--> 2147483649 (ohne Vorzeichen)

Ich bin mir im Moment nicht sicher, die Vorzeichengeschichte und DWord/DInt sind eigentlich eher ein Problem der Darstellung auf dem Bildschirm. Ob man ein Rechenergebnis als Zahl größer 2147483647 oder als neagtive Zahl interpretiert hängt letztlich davon ab, was man braucht. 

Wenn ich da falsch liege korrigiert mich bitte, hab darauf noch nie zu viele Gedanken verschwendet.




_Praktikant_ schrieb:


> Ist hier kopieren von werten aus DB in temp-var gemeint?




Summand_1, Summand_2 sind IN
Ergebnis OUT

Du legst hintereinander 3 Temp-Var an 

Summand_1_temp, Summand_2_temp, Ergebnis_temp

Die Input kopierst du in die Temp, dann kannst du mit AR1 und dem Offset alle 3 Variablen adressieren, der Ergebnis_temo zum Schluß in die Out kopieren.


```
L     32; 
      L     #Schleifenzaehler; 
      -I    ; 
      +AR1  ;
```
bedeutet:

AR1 := AR1 + (32 - #Schleifenzähler)

(Onkel macht das anders, der rechnet in jeder Schleife AR1 := AR1 + P#0.1, und baut immer auf dem AR1 aus der vorhergehenden Schleife auf. Ich rechne das AR1 jedesmal am Anfang der Schleife neu aus. Beides führt zum Ziel.)

Der Schleifenzähler beginnt ja bei 32 und wird dann von Loop bis 0 runtergezählt. Die duale Berechnung beginnt aber bei 0 und wird bis Bit 32 aufwärts durchgeführt.



_Praktikant_ schrieb:


> Was fehlt denn noch alles bei der schleife von onkel dagobert?
> XOR-verknüpfung von s1,s1 und altem übertrag und...?



Onkel hat das mit AR1 und AR2 gemacht, das geht auch.
Und er hat das AR1 und AR2 etwas anders hochgezählt für die Erhöhung der Bitnummer.
Außerdem fehlt die Berechnung des jeweils neuen Übertrages, darauf bist du ja oben eingegangen, ist in dem Wiki-Beitrag ja schön zu sehen.


----------



## maxi (16 August 2007)

Er kann auch Taschnrechner spielen.

0 + 0 ergibt 0,
0 + 1 ergibt 1,
1 + 0 ergibt 1,
1 + 1 ergibt 0 mit Übertrag von 1 auf die nächsthöherwertige Stelle.

Er Wetet den letzten Bit der beiden Binärzahlen aus und hat ein Merkberit für die nächsthöherwertge Stelle, das Ergebniss in eine neue Binärzahl.

Je nachdem ob er Word oder Doppelword oder String nimmt muss halt der Loop lang sein. 

Ist normal ne Übungsaufgabe aus Assembler.


----------



## Ralle (16 August 2007)

maxi schrieb:


> Er kann auch Taschnrechner spielen.
> 
> 0 + 0 ergibt 0,
> 0 + 1 ergibt 1,
> ...



Ja, aber er soll doch nicht addieren, jedenfalls nicht mit "+" und Add, also bleibt nur die logische Auswertung per U, O, X, UN ...


----------



## gravieren (16 August 2007)

Hi Ralle

Will hier NICHT nerven.




> Ja, aber er soll doch nicht addieren, jedenfalls nicht mit "+" und Add, also bleibt nur die logische Auswertung per U, O, X, UN ...


 Oder eine Subtraktion mit der ( 2.Zahl * -1) 
 

@Praktikant
Wurde WIRKLICH mit "Indirekter Adressierung ... " gesagt ?


----------



## maxi (16 August 2007)

Ralle schrieb:


> Ja, aber er soll doch nicht addieren, jedenfalls nicht mit "+" und Add, also bleibt nur die logische Auswertung per U, O, X, UN ...


 
Kann er ja mit Und, Oder, S, R machen.

Ich weiss aber noch was geileres 

Einen Zähler *fg*
bzw. wenn ganz ohne Addieren dann mit 3 zählern *lach*


----------



## gravieren (16 August 2007)

Hi MAXI


Ist deine Signatur defekt  ?

Server abgestürtzt  ?

Mein JAVA fehlerhaft installiert.


Irgendwie bekomme ich keine "Bewegung mehr".


----------



## maxi (16 August 2007)

Die hatten mich ned so lieb wie ich war.
Wollen nur perfekte arische Signatruren.
Ich wurde Diknriminiert! *spass*

Lassen wir die Diskussion aber, das kannst du mir Privat mitteilen. Mag keien Zirkusveranstaltung hier mehr.


----------



## gravieren (16 August 2007)

Hi Maxi

Zum Trost schau doch mal zu deinem Tread XP und SP2.


Sorry, hatte mich etwas verlesen.


----------



## Onkel Dagobert (16 August 2007)

_Praktikant_ schrieb:


> ..Was fehlt denn noch alles bei der schleife von onkel dagobert?..


 

```
[COLOR=blue]... AR1 sichern (TAR1)[/COLOR]
[COLOR=blue]... Summanden in Lokaldaten kopieren[/COLOR]
[COLOR=blue]... Adressen der Summanden in AR1 und AR2 laden (LAR1, LAR2)[/COLOR]
[COLOR=#0000ff]... Übertrag initialisieren (auf "0" setzen)[/COLOR]
 
      L     32
L001: T     #TEMP_INT
//*** Binärergebnis unter Berücksichtigung des Übertrag
      X      [AR1,P#0.0]
      X      [AR2,P#0.0]
      X     #UEBERTRAG
      =     #EINS                       // Ergebnisbit
 
//*** Übertrag
[COLOR=blue]... Ein neuer Übertrag erfolgt, wenn [/COLOR]
[COLOR=blue]... beide bits in den Zahlen "1" sind, ODER [/COLOR]
[COLOR=blue]... ein bit "1" ist UND ein aktueller Übertrag ansteht.[/COLOR]
      =     #UEBERTRAG
 
      U     #EINS
      =      [AR2,P#0.0]                // am Ende steht die Summe in AR2
 
      +AR1  P#0.1
      +AR2  P#0.1
      L     #TEMP_INT
      LOOP  L001
 
[COLOR=blue]... Summe, welche über AR2 in eine der Variablen[/COLOR]
[COLOR=blue]..."Summand" abgelegt wurde, in die Variabe "Summe" kopieren[/COLOR]
[COLOR=blue]... AR1 wieder herstellen (LAR1)[/COLOR]
[COLOR=blue].[/COLOR]
```
 
Wenn du das so umsetzt, hast du deinen ersten Erfolg. Beim Testen wirst du jedoch feststellen, dass es nicht über den ganzen 32-Bitbereich funktioniert. Aber bring es erst einmal soweit zum laufen, das solltest du schaffen.


Gruß, Onkel


----------



## _Praktikant_ (16 August 2007)

Ok, dann werd ich versuchen die sachen morgen umzusetzen :sm5:!
Was mir grad noch etwas unklar im bsp von ralle ist, sind die 4 zeilen 
1. 





> ```
> L 32
> L #Schleifenzaehler
> -I
> ...


Was ist mit T #Zaehlvar
passiert bzw. wie/wozu wird die verarbeitet?
und dann 2.


> ```
> L     32;
> L     #Schleifenzaehler;
> -I    ;
> ...


Ist doch der bitweise durchlauf der zahl (wie die andere möglichkeit von onkel)?
Danke nochmals und schönen abend noch...


----------



## Ralle (16 August 2007)

_Praktikant_ schrieb:


> 1. Was ist mit T #Zaehlvar
> passiert bzw. wie/wozu wird die verarbeitet?



Das war nur ein Anfangsbeispiel mit Zaehlvar als Zwischenmerker

Statt 

T #Zahelvar
L #ZaehlVar
+AR1

gleich

+AR1



_Praktikant_ schrieb:


> 2. Ist doch der bitweise durchlauf der zahl (wie die andere möglichkeit von onkel)?



Ja genau, das hast du richtig erkannt und damit schon mal eine ganze Menge verstanden :-D. Wie ich schon schrieb ist Onkel ein wenig anders herangegangen, das Ergebnis ist das Selbe.


----------



## _Praktikant_ (17 August 2007)

Hallo,

hier mal ein versuch von mir:

```
L     #Summand_1
      T     #Summand1_t
      L     #Summand_2
      T     #Summand2_t
      L     P##Summand1_t
      LAR1  
      L     P##Summand2_t
      LAR2  
      U     #Uebertrag
      R     #Uebertrag
      L     32
L001: T     #Schleifenzaehler
// Binärergebnis unter Berücksichtigung des Übertrag
      X      [AR1,P#0.0]
      X      [AR2,P#0.0]
      X     #Uebertrag
      =     #Ergebnis_t                 // Ergebnisbit
// Übertrag
      U      [AR1,P#0.0]
      O      [AR2,P#0.0]
      U     #Uebertrag                  //alter Übertrag
      O(    
      U      [AR1,P#0.0]
      U      [AR2,P#0.0]
      )     
      O(    
      U      [AR1,P#0.0]
      U      [AR2,P#0.0]
      U     #Uebertrag                  //alter Übertrag
      )     
      =     #Uebertrag                  //neuer Übertrag
      U     #Ergebnis_t
      =      [AR2,P#0.0]                // am Ende steht die Summe in AR2
      +AR1  P#0.1
      +AR2  P#0.1
      L     #Schleifenzaehler
      LOOP  L001
      TAR2  
      T     #Ergebnis
```
 
Ok oder nix kapiert?!?:-? 
Das speichern und wiederherstellen des AR hab ich noch nicht rausgefunden bzw. ist mir die funktion noch nicht klar; 
gibt es ein bsp irgendwo?

@gravieren
Die anderen Lösungen wären zunächst bestimmt auch ok, aber da ich ind.Adr. weiterhin brauchen werde, sollte ich mich gleich damit befassen.


----------



## Kai (17 August 2007)

Hier mal ein paar Anmerkungen von mir:

1. Ich würde die Berechnung des Übertrags etwas anders machen, siehe hierzu:

http://de.wikipedia.org/wiki/Halbaddierer

http://de.wikipedia.org/wiki/Volladdierer


2. Deine Programmschleife kann so noch nicht funktionieren. 

Du musst bedenken, wie die einzelnen Bits in einem Doppelwort in STEP 7 addressiert sind:


```
MD0
 
           MW0                         MW2
 
    MB0           MB1           MB2           MB3
 
M0.7 - M0.0   M1.7 - M1.0   M2.7 - M2.0   M3.7 - M3.0
```
 
Gruß Kai


----------



## Ralle (17 August 2007)

_Praktikant_ schrieb:


> Hallo,
> 
> hier mal ein versuch von mir:
> 
> ...



du schreibst ja
 =      [AR2,P#0.0]                // am Ende steht die Summe in AR2

TAR2 Brauchst du nicht, würde so ja auch die Adresse von AR2 in dein Ergebnis transferrieren.

es reicht

L #P_Summand2_t, da steht ja das Ergebnis


----------



## _Praktikant_ (19 August 2007)

Hallo,

könnte mir jmd ein beispiel geben oder sagen was genau jetzt noch
geändert werden muß?!?
Die adressierung bzw der durchlauf beginnt dann also im "rechten teil"
der einzelnen doppelwörter (zb S1 -> 3.0);
dann gäbe es doch nach jedem byte ein rücksprung auf die nächste adresse? 
Ist meine übertrags berechnung dann falsch oder die andere verknüpfung einfach besser? 
Danke schon mal, mfg...


----------



## Onkel Dagobert (19 August 2007)

Hallo Praktikant,

Befehl *TAD* ansehen - hatte mal einer geschrieben  !
Nun gut, ich denke man sollte dich nicht länger zappeln lassen.


```
FUNCTION FC 1 : VOID
TITLE =
VERSION : 0.1
VAR_INPUT
  SUMMAND_A : DINT ; 
  SUMMAND_B : DINT ; 
END_VAR
VAR_OUTPUT
  SUMME : DINT ; 
END_VAR
VAR_TEMP
  SAVE_AR1 : DWORD ; 
  SA : DINT ; 
  SB : DINT ; 
  TEMP_INT : INT ; 
  UEBERTRAG : BOOL ; 
  EINS : BOOL ; 
  TEMP : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE =
//
//    Es gelten folgende Regeln
//    0+0=0
//    1+0=1
//    0+1=1
//    1+1=0 Übertrag 1
//
      TAR1  #SAVE_AR1; 
      SET   ; 
      SAVE  ; 
      L     #SUMMAND_A; 
      TAD   ; 
      T     #SA; 
      L     #SUMMAND_B; 
      TAD   ; 
      T     #SB; 
      L     P##SA; 
      LAR1  ; 
      L     P##SB; 
      LAR2  ; 
      CLR   ; 
      =     #UEBERTRAG; 
      L     32; 
L001: T     #TEMP_INT; 
//*** Binärergebnis unter Berücksichtigung des Übertrag
      X      [AR1,P#0.0]; 
      X      [AR2,P#0.0]; 
      X     #UEBERTRAG; 
      =     #EINS; // Ergebnisbit
//*** Übertrag
      U      [AR1,P#0.0]; // wenn beide bits "1"
      U      [AR2,P#0.0]; 
      O     ; 
      U     #UEBERTRAG; // oder wenn Übertrag
      U(    ; // und genau ein bit "1"
      X      [AR1,P#0.0]; 
      X      [AR2,P#0.0]; 
      )     ; 
      =     #UEBERTRAG; 
      U     #EINS; 
      =      [AR2,P#0.0]; // am Ende Summe in AR2
      +AR1  P#0.1; 
      +AR2  P#0.1; 
      L     #TEMP_INT; 
      LOOP  L001; 
      L     #SB; // Summe wurde in AR2 (#SB) geschrieben
      TAD   ; 
      T     #SUMME; 
      LAR1  #SAVE_AR1; 
END_FUNCTION
```
 

Gruß, Onkel


----------



## Ralle (19 August 2007)

@Onkel

Ja, hast Recht.

@Praktikant

Ich hab es fast so wie Onkel gemacht, allerdings nur mit AR1. Der Code ist sich natürlich auf Grund der Aufgabe ähnlich. Wenn es dich interessiert, stell ich das auch noch hier ein, ansonsten bleiben wir bei Onkels Version, sonst gibts noch Codesalat .


----------



## _Praktikant_ (20 August 2007)

Hallo, 

vielen dank für die hilfe !!
Ich habs glaub ich auch soweit kapiert,
nur die 4 zeilen





> ```
> TAR1  "SAVE_AR1"
> SET
> SAVE
> ...


 sind mir noch unklar?!
In der hilfe steht nicht viel, für was genau brauche ich die AR-Operationen?

@Ralle 
Deine Version würd mich auch interessieren und was war jetzt egtl.
die Siemens-Stolperfalle?!
Gruß


----------



## Ralle (20 August 2007)

Jo dann, hier mal meine Version:


```
FUNCTION FC 50 : VOID
TITLE =
VERSION : 1.0
AUTHOR : Ralle

VAR_INPUT
  Summand_1 : DWORD ;    
  Summand_2 : DWORD ;    
END_VAR
VAR_OUTPUT
  Ergebnis : DWORD ;    
END_VAR
VAR_TEMP
  Schleifenzaehler : WORD ;    
  Uebertrag_Temp : BOOL ;    
  SAVE_VKE : BOOL ;    
  Summand_1_Temp : DWORD ;    
  Summand_2_Temp : DWORD ;    
  Ergebnis_Temp : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =Sichere VKE im BIE

      SET   ; 
      SAVE  ; 
      =     #SAVE_VKE; 
NETWORK
TITLE =

// Laden der beiden Doppelwörter      
      L     #Summand_1; 
      TAD   ; //Bytes tauschen
      T     #Summand_1_Temp; 

      L     #Summand_2; 
      TAD   ; //Bytes tauschen
      T     #Summand_2_Temp; 

      L     0; 
      T     #Ergebnis_Temp; 

      CLR   ; 
      =     #Uebertrag_Temp; 

      L     L#32; 
loop: T     #Schleifenzaehler; 

      L     P##Summand_1_Temp; 
      LAR1  ; 

      L     32; 
      L     #Schleifenzaehler; 
      -I    ; 
      +AR1  ; 

//Ergebnisbit berechnen  
      X      [AR1,P#0.0]; //summand1
      X      [AR1,P#4.0]; //summand2
      X     #Uebertrag_Temp; //übertrag
      =      [AR1,P#8.0]; //ergebnis

//nächsten Übertrag berechnen
      U      [AR1,P#0.0]; //summand1
      U      [AR1,P#4.0]; //summand2
      U     #Uebertrag_Temp; //übertrag
      O     ; 
      U      [AR1,P#0.0]; //summand1
      U      [AR1,P#4.0]; //summand2
      UN    #Uebertrag_Temp; //übertrag
      O     ; 
      U      [AR1,P#0.0]; //summand1
      UN     [AR1,P#4.0]; //summand2
      U     #Uebertrag_Temp; //übertrag
      O     ; 
      UN     [AR1,P#0.0]; //summand1
      U      [AR1,P#4.0]; //summand2
      U     #Uebertrag_Temp; //übertrag
      =     #Uebertrag_Temp; //nächster übertrag

      L     #Schleifenzaehler; 
      LOOP  loop; 

//Ergebnis speichern

      L     #Ergebnis_Temp; 
      TAD   ; //Bytes zurück tauschen
      T     #Ergebnis; 
NETWORK
TITLE =

      U     #SAVE_VKE; 
      SAVE  ; 
      BE    ; 
END_FUNCTION
```
Das Berechnen des Übertrages hat Onkel kürzer hinbekommen .

Die Stolperfalle, war das TAD. Laß mal alle TAD weg, dann funktioniert es, bis man mit seinem Ergebnis eine Bytegrenze überschreitet. Probiers mal aus.

TAR1  "SAVE_AR1" rettet das AR 1 in einen Zwischenspeicher
LAR1  "SAVE_AR1" holt das gerettete AR1 wieder zurück

Mit AR1 muß man das nicht unbedingt machen, bei AR2 ist es aber anzuraten, da das AR2 von Multi-FB genutzt wird.

SAVE speichert das VKE im BIE-Bit (Siehe dazu ausführlich die Step7-Hilfe)


----------



## _Praktikant_ (20 August 2007)

Ok, alles klar:sm5: !
Danke für eure hilfe,
hab bestimmt mal wieder ne frage...
Gruß:s12:


----------



## godi (20 August 2007)

Hallo!

Habe das ganze mal als Übung in SCL mit 3 Summanden Programmiert.

Jetzt würde mich mal interessieren ob man das besser auch noch machen kann oder ob meine Lösung schon in Ordnung ist! :-D 


```
FUNCTION_BLOCK FB4
 
VAR_INPUT
    Start : BOOL;
    Summand_1 : DINT;
    Summand_1_Byte AT Summand_1 : ARRAY [0..3] OF BYTE;
    Summand_2 : DINT; 
    Summand_2_Byte AT Summand_2 : ARRAY [0..3] OF BYTE;  
    Summand_3 : DINT;
    Summand_3_Byte AT Summand_3 : ARRAY [0..3] OF BYTE;
END_VAR
 
VAR_OUTPUT
    Summe : DINT;
    Summe_Byte AT Summe : ARRAY [0..3] OF BYTE;
END_VAR
 
VAR_TEMP
 
END_VAR
 
VAR
  Bit_Nr : INT;
    Bit_Ueberlauf_1 : BOOL;
    Bit_Ueberlauf_2 : BOOL;
    Zwischenergebnis_1 : DINT;
    Zwischenergebnis_1_Bit AT Zwischenergebnis_1 : ARRAY [0..31] OF BOOL;
    Summand_1_TAD : DINT;
    Summand_1_TAD_Byte AT Summand_1_TAD : ARRAY [0..3] OF BYTE;
    Summand_1_TAD_Bit AT Summand_1_TAD : ARRAY [0..31] OF BOOL;
    Summand_2_TAD : DINT;
    Summand_2_TAD_Byte AT Summand_2_TAD : ARRAY [0..3] OF BYTE;
    Summand_2_TAD_Bit AT Summand_2_TAD : ARRAY [0..31] OF BOOL;
    Summand_3_TAD : DINT;
    Summand_3_TAD_Byte AT Summand_3_TAD : ARRAY [0..3] OF BYTE;
    Summand_3_TAD_Bit AT Summand_3_TAD : ARRAY [0..31] OF BOOL;
    Summe_TAD : DINT;
    Summe_TAD_Bit AT Summe_TAD : ARRAY [0..31] OF BOOL;
    Summe_TAD_Byte AT Summe_TAD : ARRAY [0..3] OF BYTE;
END_VAR
 
BEGIN
 
//Tausche Bytes in Summand 1
Summand_1_TAD_Byte[0] := Summand_1_Byte[3];
Summand_1_TAD_Byte[1] := Summand_1_Byte[2];
Summand_1_TAD_Byte[2] := Summand_1_Byte[1];
Summand_1_TAD_Byte[3] := Summand_1_Byte[0];
 
//Tausche Bytes in Summand 2
Summand_2_TAD_Byte[0] := Summand_2_Byte[3];
Summand_2_TAD_Byte[1] := Summand_2_Byte[2];
Summand_2_TAD_Byte[2] := Summand_2_Byte[1];
Summand_2_TAD_Byte[3] := Summand_2_Byte[0];
 
//Tausche Bytes in Summand 3
Summand_3_TAD_Byte[0] := Summand_3_Byte[3];
Summand_3_TAD_Byte[1] := Summand_3_Byte[2];
Summand_3_TAD_Byte[2] := Summand_3_Byte[1];
Summand_3_TAD_Byte[3] := Summand_3_Byte[0];
 
//Beginne mit Addierer
IF Start THEN                       //Startbedienung
    Summe_TAD := 0;
    Zwischenergebnis_1 := 0;
    Bit_Ueberlauf_1 := false;
 
    FOR Bit_Nr := 0 TO 31 DO        //Addiere ersten zwei Summanden
        IF Summand_1_TAD_Bit[Bit_Nr] XOR Summand_2_TAD_Bit[Bit_Nr] XOR Bit_Ueberlauf_1 THEN
            Zwischenergebnis_1_Bit[Bit_Nr] := true;
        END_IF;
        Bit_Ueberlauf_1 := Summand_1_TAD_Bit[Bit_Nr] AND Summand_2_TAD_Bit[Bit_Nr] OR Bit_Ueberlauf_1 AND (Summand_1_TAD_Bit[Bit_Nr] OR Summand_2_TAD_Bit[Bit_Nr]);
 
    END_FOR; 
 
    Bit_Ueberlauf_2 := false;
    FOR Bit_Nr := 0 TO 31 DO        //Addiere dritten Summand zum Zwischenergebnis
         IF Zwischenergebnis_1_Bit[Bit_Nr] XOR Summand_3_TAD_Bit[Bit_Nr] XOR Bit_Ueberlauf_2 THEN
            Summe_TAD_Bit[Bit_Nr] := true;
        END_IF;
        Bit_Ueberlauf_2 := Zwischenergebnis_1_Bit[Bit_Nr] AND Summand_3_TAD_Bit[Bit_Nr] OR Bit_Ueberlauf_2 AND (Zwischenergebnis_1_Bit[Bit_Nr] OR Summand_3_TAD_Bit[Bit_Nr]);
 
    END_FOR;        
END_IF;
 
//Tausche Bytes in Summe
Summe_Byte[0] := Summe_TAD_Byte[3];
Summe_Byte[1] := Summe_TAD_Byte[2];
Summe_Byte[2] := Summe_TAD_Byte[1];
Summe_Byte[3] := Summe_TAD_Byte[0];
 
END_FUNCTION_BLOCK
```
 
godi


----------



## Ralle (21 August 2007)

@godi

Ah, jetzt weiß ich wozu du nach dem TAD gefragt hast . Ich geh mal davon aus, daß du es getestet hast und es so funktioniert. Sieht doch nicht schlecht aus. Der Aufwand erscheint aber doch recht hoch, da bin ich dann doch zum Schluß froh, daß es "richtige" Addierbefehle gibt . Aber eine prima Übung, würde ich sagen.


----------



## godi (21 August 2007)

Ralle schrieb:


> @godi
> 
> Ah, jetzt weiß ich wozu du nach dem TAD gefragt hast . Ich geh mal davon aus, daß du es getestet hast und es so funktioniert. Sieht doch nicht schlecht aus. Der Aufwand erscheint aber doch recht hoch, da bin ich dann doch zum Schluß froh, daß es "richtige" Addierbefehle gibt . Aber eine prima Übung, würde ich sagen.


 
Ja deshalb die Frage nach dem TAD!  
Aber so bekomme ich auch in SCL ein wenig Übung und lerne was dazu!
Wie gesagt bei dem Beispiel sollte ich die ganze TAD geschichte über Funktionen machen da es den Code sehr stark aufbläst.


----------



## Steve81 (21 August 2007)

Hallo,

gibt es eine Möglichkeit so etwas:


```
Summand_1_TAD_Byte[0] := Summand_1_Byte[3];
Summand_1_TAD_Byte[1] := Summand_1_Byte[2];
Summand_1_TAD_Byte[2] := Summand_1_Byte[1];
Summand_1_TAD_Byte[3] := Summand_1_Byte[0];
```
 
in einer Zeile zu programmieren?

In etwa so:


```
Summand_1_TAD_Byte[0..3] := Summand_1_Byte[0], Summand_1_Byte[1], Summand_1_Byte[2], Summand_1_Byte[3];
```


----------



## Ralle (21 August 2007)

Steve81 schrieb:


> Hallo,
> 
> gibt es eine Möglichkeit so etwas:
> 
> ...



Ich glaube nicht, aber probiere es doch aus .
Wem dieser "TAD-Ersatz" zu lang ist, der kann sich auch eine kleine Funktion in AWL schreiben, die diesen TAD-Befehl beinhaltet und diese Funktion dann in SCL aufrufen. So ähnlich ginge das auch, für deine Schreibweise, kommen halt noch der Funktionsaufruf, die Klammern und die Zuweisungen dazu, ist aber dann auch nicht wirklich kürzer.


----------



## godi (21 August 2007)

Ist gerade hier besprochen worden!


----------



## godi (21 August 2007)

so jetzt noch mit Bausteinaufruf "TAD für DInt"


```
FUNCTION_BLOCK FB4

VAR_INPUT
    Start : BOOL;
    Summand_1 : DINT;
    Summand_2 : DINT; 
    Summand_3 : DINT;
END_VAR
 
VAR_OUTPUT
    Summe : DINT;
    Summe_Byte AT Summe : ARRAY [0..3] OF BYTE;
END_VAR
    
VAR_TEMP
        
END_VAR
 
VAR
  Bit_Nr : INT;
    Bit_Ueberlauf_1 : BOOL;
    Bit_Ueberlauf_2 : BOOL;
    Zwischenergebnis_1 : DINT;
    Zwischenergebnis_1_Bit AT Zwischenergebnis_1 : ARRAY [0..31] OF BOOL;
    Summand_1_TAD : DINT;
    Summand_1_TAD_Bit AT Summand_1_TAD : ARRAY [0..31] OF BOOL;
    Summand_2_TAD : DINT;
    Summand_2_TAD_Bit AT Summand_2_TAD : ARRAY [0..31] OF BOOL;
    Summand_3_TAD : DINT;
    Summand_3_TAD_Bit AT Summand_3_TAD : ARRAY [0..31] OF BOOL;
    Summe_TAD : DINT;
    Summe_TAD_Bit AT Summe_TAD : ARRAY [0..31] OF BOOL;
END_VAR
 
BEGIN

//Tausche Bytes in Summand 1
"TAD für DInt"(Input := Summand_1  // IN: DINT
               ,Output := Summand_1_TAD // OUT: DINT
               ); // VOID
 
//Tausche Bytes in Summand 2
"TAD für DInt"(Input := Summand_2  // IN: DINT
               ,Output := Summand_2_TAD // OUT: DINT
               ); // VOID
 
//Tausche Bytes in Summand 3
"TAD für DInt"(Input := Summand_3  // IN: DINT
               ,Output := Summand_3_TAD // OUT: DINT
               ); // VOID
 
//Beginne mit Addierer
IF Start THEN                       //Startbedienung
    Summe_TAD := 0;
    Zwischenergebnis_1 := 0;
    Bit_Ueberlauf_1 := false;
    FOR Bit_Nr := 0 TO 31 DO        //Addiere ersten zwei Summanden
        IF Summand_1_TAD_Bit[Bit_Nr] XOR Summand_2_TAD_Bit[Bit_Nr] XOR Bit_Ueberlauf_1 THEN
            Zwischenergebnis_1_Bit[Bit_Nr] := true;
        END_IF;
        Bit_Ueberlauf_1 := Summand_1_TAD_Bit[Bit_Nr] AND Summand_2_TAD_Bit[Bit_Nr] OR Bit_Ueberlauf_1 AND (Summand_1_TAD_Bit[Bit_Nr] OR Summand_2_TAD_Bit[Bit_Nr]);
       
    END_FOR; 
    Bit_Ueberlauf_2 := false;
    FOR Bit_Nr := 0 TO 31 DO        //Addiere dritten Summand zum Zwischenergebnis
         IF Zwischenergebnis_1_Bit[Bit_Nr] XOR Summand_3_TAD_Bit[Bit_Nr] XOR Bit_Ueberlauf_2 THEN
            Summe_TAD_Bit[Bit_Nr] := true;
        END_IF;
        Bit_Ueberlauf_2 := Zwischenergebnis_1_Bit[Bit_Nr] AND Summand_3_TAD_Bit[Bit_Nr] OR Bit_Ueberlauf_2 AND (Zwischenergebnis_1_Bit[Bit_Nr] OR Summand_3_TAD_Bit[Bit_Nr]);
       
    END_FOR;        
END_IF;
 
//Tausche Bytes in Summe
"TAD für DInt"(Input := Summe_TAD  // IN: DINT
               ,Output := Summe // OUT: DINT
               ); // VOID
 
END_FUNCTION_BLOCK
```
 
sieht doch gleich besser aus!


----------



## Steve81 (21 August 2007)

Ralle schrieb:


> Ich glaube nicht, aber probiere es doch aus .
> Wem dieser "TAD-Ersatz" zu lang ist, der kann sich auch eine kleine Funktion in AWL schreiben, die diesen TAD-Befehl beinhaltet und diese Funktion dann in SCL aufrufen. So ähnlich ginge das auch, für deine Schreibweise, kommen halt noch der Funktionsaufruf, die Klammern und die Zuweisungen dazu, ist aber dann auch nicht wirklich kürzer.


 
Es ging mir hauptsächlich darum, ob man einem Array mehrere Variables in einer Programmeile zuweisen kann und nicht unbedingt um einen Ersatz für TAD.
So wie es aussieht geht es aber nur mit absoluten Werten.

So gehts:

```
Feld[0..3] := 4, 8, 2, 5;
```
 
So gehts leider nicht:


```
Feld[0..3] := W0, W1, W2, W3;
```


----------



## Kai (23 August 2007)

_Praktikant_ schrieb:


> Zur Einübung soll ich 2 (32bit) Dualzahlen addieren, aber ohne die vorhandene Add.funktion.


 
Hier noch einmal eine Lösung der Aufgabe unter Verwendung der speicherindirekter Adressierung mit Zeigern im Lokaldatenbereich der Funktion. Der Vorteil der speicheindirekten Adressierung ist, dass man mit mehreren Zeigern gleichzeitig arbeiten kann. 


```
// FC100 : Addierer
 
// Adressregister AR1 sichern
 
      TAR1  #AR1_TEMP
 
 
// Addierer
 
// Summand 1, Summand 2
 
      L     #SUMMAND_1                  // Summand 1
      TAD   
      T     #SUMMAND_1_TEMP             // Summand 1
 
      L     #SUMMAND_2                  // Summand 2
      TAD   
      T     #SUMMAND_2_TEMP             // Summand 2
 
      L     L#0                         // Summe
      T     #SUMME_TEMP
 
      CLR   
      =     #UEBERTRAG_TEMP             // Übertrag
 
// Zeiger
 
      L     P##SUMMAND_1_TEMP           // Zeiger Summand 1
      T     #SUMMAND_1_ZEIGER
 
      L     P##SUMMAND_2_TEMP           // Zeiger Summand 2
      T     #SUMMAND_2_ZEIGER
 
      L     P##SUMME_TEMP               // Zeiger Summe
      T     #SUMME_ZEIGER
 
// Schleife
 
      L     32
M01:  T     #SCHLEIFE                   // Schleife
 
// Summe
 
      X     L [#SUMMAND_1_ZEIGER]       // Summand 1
      X     L [#SUMMAND_2_ZEIGER]       // Summand 2
      X     #UEBERTRAG_TEMP             // Übertrag
      =     L [#SUMME_ZEIGER]           // Summe
 
// Übertrag
 
      U     L [#SUMMAND_1_ZEIGER]       // Summand 1
      U     L [#SUMMAND_2_ZEIGER]       // Summand 2
      O     
      U     L [#SUMMAND_1_ZEIGER]       // Summand 1
      U     #UEBERTRAG_TEMP             // Übertrag
      O     
      U     L [#SUMMAND_2_ZEIGER]       // Summand 2
      U     #UEBERTRAG_TEMP             // Übertrag
      =     #UEBERTRAG_TEMP             // Übertrag
 
// Zeiger
 
      L     #SUMMAND_1_ZEIGER           // Zeiger Summand 1
      L     L#1
      +D    
      T     #SUMMAND_1_ZEIGER           // Zeiger Summand 1
 
      L     #SUMMAND_2_ZEIGER           // Zeiger Summand 2
      L     L#1
      +D    
      T     #SUMMAND_2_ZEIGER           // Zeiger Summand 2
 
      L     #SUMME_ZEIGER               // Zeiger Summe
      L     L#1
      +D    
      T     #SUMME_ZEIGER               // Zeiger Summe
 
// Schleife
 
      L     #SCHLEIFE                   // Schleife
      LOOP  M01
 
// Summe
 
      L     #SUMME_TEMP                 // Summe
      TAD   
      T     #SUMME                      // Summe
 
 
// Adressregister AR1 wiederherstellen
 
      LAR1  #AR1_TEMP
```
 
Gruß Kai


----------

