Automtische Multiplikation in DB speichern

Nordischerjung

Level-2
Beiträge
826
Reaktionspunkte
111
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin liebe Gemeinde,

ich progge zur Zeit an einer 315T-2DP mit CU320 herrum.
Hier brauche ich eine Rechnung und weiss leider nicht so recht wie.
Ich habe einen positiven Wert X (INT) z.B. 512, den muss ich dann mit einem Wert Y (INT) z.b. 8 multiplizieren.
z.B. 0 x 512, 1 x 512, 2 x 512, usw bis Wert Y hier im Beispiel 8. Jedes Ergebnis muss ich im DB ab DBW 0 speichern,
Ergebnis 1 DBW0, Ergebnis 2 DBW2 usw. Im DB habe ich ein Array [254] of Int.
Wie progge ich dass?
Vor lauter Schleifen usw blick ich irgendwie nicht durch.:confused:

Gruß von der Ostsee

Nordischerjung
 
hi

du brauchst im eigentlichen nur 1 Schleife
der y wert ist dein Schleifenzähler (Merker od. temp.)
den x speicherst du in einen Merker
den rest kannst du mit temp. variablen machen die du pro schleifen durchlauf incementierst.
auf den Db kannst du mit zeigern schreiben.

lg freezer
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
danke für deine Antwort.
Hört sich so ganz einfach an ;) aber...
bei der Umsetzung hängt es. Das mit der Schleife werde ich hoffentlich irgendwie
hin bekommen, aber wie und wann speicher ich die Ergebnisse in den DB?
Kommt das auch in die Schleife?
 
Geht doch eigentlich ganz einfach.

1. Wert 1 einlesen
2. Wert 2 einlesen
3. ausrechen
4. Wert mit flanke in Datenbaustein speichern


also mal los, wenn du ein Problem hast, stell den Code hier rein, denn du willst es ja lernen, einige hier können es schon ;)


bike
 
Hab mir jetzt mal etwas zusammen gestellt in FC1.
Kann man das so machen?

Code:
       TAR1 #AR1_temp                    //AR1 sichern in Temp Var DWORD

       AUF  DB      100

       L    P#        2.0                //Adresse der 1. DB Variablen laden und (hier DBW 2, da DBW0 immer 0 ist)
       T    #Pointer_temp                    
       
       L    #Input_1                     //Lade den ersten Eingangswert 
       T    #Input_1_temp            //Speichern auf temp. Variable

       L    #Input_2                     //Anzahl den Multiplikator
Loop  :T    #Count                     //Zähler für Schleife
       
       L    #Pointer_temp                     //Pointer für DB
       LAR1

       L    #Init                           //Eingabewert 1 Temp
       L    #Count                       //Lade den Zähler der Schleife
       *I                               
       T    DBW [AR1,P#0.0]          // lädt das DBW

       L    #Pointer_temp                    //Zeiger nach Akku 1 transferieren / 
       L    P#        2.0                //Wordadresse des Zeigers um 2 Byte erhöhen (Typ: INT)
       +I                                
       T    #Pointer_temp                    //Neue Adresse in Zeiger laden

       L    #Count                       //Schleifenzähler laden
       LOOP Loop

End   :NOP  0
 
       LAR1 #AR1_temp                    //AR1 zurück schreiben
Wie kann ich es denn jetzt proggen, dass die Schleife nicht von Oben nach unten zählt,
sondern umgekehrt. Ich benötige den kleinsten Wert zuerst

Gruß Nordischerjung
 
GutenMorgen

Hallo, hallo,


habe den Code mal kurz überflogen.

Sieht doch ganz hübsch aus.

Code:
*I                               
       T    DBW [AR1,P#0.0]          // lädt das DBW

       L    #Pointer_temp                    //Zeiger nach Akku 1 transferieren / 
       L    P#        2.0                //Wordadresse des Zeigers um 2 Byte erhöhen (Typ: INT)
       +I                                
       T    #Pointer_temp                    //Neue Adresse in Zeiger laden

       L    #Count                       //Schleifenzähler laden
       LOOP Loop
Ich würde das +I gegen ein +D tauschen.

Code:
*I                               
       T    DBW [AR1,P#0.0]          // lädt das DBW

       L    #Pointer_temp                    //Zeiger nach Akku 1 transferieren / 
       L    P#        2.0                //Wordadresse des Zeigers um 2 Byte erhöhen (Typ: INT)
      [COLOR=Red] +D [/COLOR]                              
       T    #Pointer_temp                    //Neue Adresse in Zeiger laden

       L    #Count                       //Schleifenzähler laden
       LOOP Loop
Gruß

Dominik
 
Habe es jetzt hoffentlich geschafft.
Es ist auch noch das Löschen der alten Daten dazu gekommen, falls das nächste Beschreiben kleiner Ist als das voherige.
(Das ist aber nur zur Übung für mich) :D
Auf jeden fall habe ich so einen guten Überblick von der Pointer und Zeiger Geschichte bekommen

Code:
     TAR1  #AR1_temp                   //AR1 sichern in Temp Var DWORD

      AUF   "DB10_Speicherpos"          //DB 10 auschlgaen

      L     0.000000e+000               //Lade 0 in 
      T     DBD    0                    //1. DBD, da der 1.Wert immer 0 ist

      L     P#4.0                       //Adresse der 1. DB Variablen laden (hier DBD .04, da DBD 0.0 immer 0 ist)
      T     #Pointer_temp

      L     #Input_1                    //Lade den ersten Eingangswert
      T     #Input_1_temp               //Speichern auf temp. Variable

      L     #Input_2                    //Lade den Multiplikator
      L     1                           //subtrahiere , da Schleife nicht bei 0
      -I                                //arbeitet
Loop: T     #Count                      //Zähler für Schleife

      L     #Input_2                    //Lade den Multiplikator 
      L     #Count                      //Lade Zähler Schleife und subtrahiere von Multiplikator
      -I                                //damit der kleinste Wert als erstes im DB steht
      T     #multiplik

      L     #Pointer_temp               //Pointer für DB
      LAR1  

      L     #multiplik                  //Lade den gerechneten Zähler der Schleife
      DTR   
      L     #Input_1_temp               //Eingabewert 1 Temp
      *R    
      T     DBD [AR1,P#0.0]             // lädt das DBD

      L     #Pointer_temp               //Zeiger nach Akku 1 transferieren 
      L     P#4.0                       //Wordadresse des Zeigers um 2 Byte erhöhen (Typ: INT)
      +D    
      T     #Pointer_temp               //Neue Adresse in Zeiger laden

      L     #Count                      //Schleifenzähler laden
      LOOP  Loop
NW2
Code:
      L     #Input_2                    //Lade den Multiplikator
      L     4                           //mit 4 multiplizieren 
      *I                                //um 1. freie Anfangsdresse im DB zu bekommen
      T     #anfang_BYTE

      L     49                          //maximale DB Länge
      L     #Input_2                    //belegte DBD subtrahieren
      -I    
      T     #unbenutzte_DBD

      L     #Input_2                    //Wenn >49 kein SFC21 Aufruf
      L     49                          //springe zu ende
      >I    
      SPB   ende
NW3
Code:
      L     B#16#10                     //10h für s7
      T     LB    30
      L     B#16#8                      //Typ REAL
      T     LB    31
      L     #unbenutzte_DBD             //Anzahl (Wiederholungsfaktor)
      T     LW    32
      L     0                           //*1 Datenbaustein (hier 0 da wir ja auf
      T     LW    34                    //   einen Merkerbereich zugreifen wollen) 
      L     200                         //Anfangsadresse M200.0
      SLD   3                           //Pointer bauen
      T     LD    36
      L     B#16#83                     //Speicherbereich (hier Merker)
      T     LB    36
NW4
Code:
//Any Zeiger für DB 10 ab welcher Position mit = geschrieben wird

      L     B#16#10                     //10h für s7
      T     LB    40
      L     B#16#8                      //Typ REAL
      T     LB    41
      L     #unbenutzte_DBD             //Anzahl (Wiederholungsfaktor)
      T     LW    42
      L     10                          //Datenbaustein  10
      T     LW    44                    //    
      L     #anfang_BYTE                //Anfangsadresse
      SLD   3                           //Pointer bauen
      T     LD    46
      L     B#16#84                     //Speicherbereich (hier DB)
      T     LB    46
NW5
Code:
      CALL  "FILL"
       BVAL   :=#Zeiger_Quelle
       RET_VAL:=#retval
       BLK    :=#Zeiger_DB_Ziel



ende: NOP   0
      LAR1  #AR1_temp                   //AR1 zurück schreiben
Könnte man es so erstelle oder ist das zu aufwendig und geht es eleganter?
 
Zuletzt bearbeitet:
Macht dein Programm was du willst?
Wenn ja ist es doch gut, wenn nicht musst du es anpassen.

<Zitat> Programmierer sind Künstler und welcher Künstler lässt sich schon gern in seine Kunst dreinreden? <Zitat Ende>


bike
 
Zuviel Werbung?
-> Hier kostenlos registrieren
.....
[/CODE]NW5
Code:
      CALL  "FILL"
       BVAL   :=#Zeiger_Quelle
       RET_VAL:=#retval
       BLK    :=#Zeiger_DB_Ziel



ende: NOP   0
      LAR1  #AR1_temp                   //AR1 zurück schreiben
Könnte man es so erstelle oder ist das zu aufwendig und geht es eleganter?

1. Was machst du denn mit dem "FILL" ?? wenn du das zum kopieren benutzt würde ich eher den SFC20 (BlockMove) benutzen.
2. Wieso speicherst du das Adressregister und lädst es wieder zurück ??

Gruß Philip
 
Code:
1. Was machst du denn mit dem "FILL" ??
Mit dem FILL (SFC21) beschreibe ich die nicht benutzten DBDs mit 0

Code:
2. Wieso speicherst du das Adressregister und lädst es wieder zurück ??
Weil ich das Adressregister damit sichere. Hab ich hier im Forum gelernt.:s12:
Man weiß nie was ein Siemensbaustein so macht. :D :rolleyes:

Macht dein Programm was du willst?
Wenn ja ist es doch gut, wenn nicht musst du es anpassen.
Hast ja recht, hätte doch sein können, dass es noch tricks gibt. Aber es funktioniert so

Edit:

Wie ich aber festgestellt habe, brauch ich bei SFC21 BVAL kein Zeiger basteln. Es reicht wenn ich dort ein MW dran schreibe.
Tststs alles umsonst, ich dachte man muss den gleichen Bereich übergeben, aber hier liegt scheinbar der Unterschied zu SFC20 BlockMove.

Code:
L 0
T MW200

CALL SFC21
   BVAL:=MW200
   RET_VAL:=#retval
   BLK:=#Zeiger_DB_Ziel
 
Zuletzt bearbeitet:
Zurück
Oben