Addierer

Zuviel Werbung?
-> Hier kostenlos registrieren
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

Code:
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
 
@godi

Ah, jetzt weiß ich wozu du nach dem TAD gefragt hast :rolleyes:. 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 :ROFLMAO:. Aber eine prima Übung, würde ich sagen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@godi

Ah, jetzt weiß ich wozu du nach dem TAD gefragt hast :rolleyes:. 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 :ROFLMAO:. 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.
 
Hallo,

gibt es eine Möglichkeit so etwas:

Code:
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:

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

gibt es eine Möglichkeit so etwas:

Code:
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:

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

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.
 
so jetzt noch mit Bausteinaufruf "TAD für DInt"

Code:
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! ;)
 
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:
Code:
Feld[0..3] := 4, 8, 2, 5;

So gehts leider nicht:

Code:
Feld[0..3] := W0, W1, W2, W3;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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.

Code:
// 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
 

Anhänge

  • OB1.pdf
    3,3 KB · Aufrufe: 8
  • FC100.pdf
    4,5 KB · Aufrufe: 8
Zurück
Oben