Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 10 von 10

Thema: Indirekte Adressierung

  1. #1
    Registriert seit
    13.11.2014
    Ort
    Paderborn
    Beiträge
    194
    Danke
    15
    Erhielt 13 Danke für 12 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo liebe Gemeinde,

    ich brauch mal wieder eure Hilfe.

    Es soll alle 50ms ein Wert in einen DB abgespeichert werden.

    Der Datentyp ist Real.

    Zuerst habe ich ein DB10 mit einem Array[0..49] erstellt in Real.
    Dann dachte ich an so etwas:

    AUF DB10

    L Z1
    SLD3
    LAR1
    T MD 180 //Dword- Pointer hinterlegt

    L DB1.DBD8 //Realtyp- Signalwert
    T DBW[MD180] //Wert soll das entsprechende Array im DB10 hinterlegt werden



    Der DB1.DBD8 verändert sich kontinuierlich und Z1 wird alle 100ms hochgezählt. Vorher im Programm ist noch eine Abfrage ob sich Z1 geändert hat, so dass nur bei einer Z1 Änderung der obige Programmabschnitt aufgerufen wird.

    Irgendwie läuft es nicht bei mir, ich habe da eine Vermutung dass es mit den Datentypen zu tun hat.

    Was mache ich falsch?


    alternativ, Wenn ich es ganz einfach halte:

    AUF DB 10

    L 1
    SLD 3
    LAR1
    T MD 180 //dword
    L DB1.DBD 8 //real
    T DBW [MD 180]

    dann geht es auch nicht. irgendas mit den Datentypen stimmt nicht, aber bei mir dreht sich auch schon alles. Ich hoffe dass ihr mir ein paar gute Tipps geben könnt
    Geändert von Junge (05.08.2015 um 17:11 Uhr)
    Zitieren Zitieren Indirekte Adressierung  

  2. #2
    Registriert seit
    21.07.2003
    Ort
    Bangkok / Thailand
    Beiträge
    98
    Danke
    24
    Erhielt 7 Danke für 7 Beiträge

    Standard

    Hallo Junge,

    was mir auf Anhieb auffällt ist dass du:

    T DBW [MD180] benutzt.

    Besser wäre es

    T DBD [MD180]

    Der Real-Wert liegt in einem DoppelWort

    L DB1.DBD 8

    Also muss das Ziel auch ein DoppelWort sein!

    Besser wäre es vielleicht das

    AUF DB10 direkt vor
    T DBD [MD180] zu schreiben.

    Dadurch erkennt man besser wohin der Wert geschrieben wird...


    Gruß
    Guido
    Geändert von Guido (05.08.2015 um 17:34 Uhr)

  3. #3
    Avatar von Junge
    Junge ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    13.11.2014
    Ort
    Paderborn
    Beiträge
    194
    Danke
    15
    Erhielt 13 Danke für 12 Beiträge

    Standard

    L Z1
    SLD3
    LAR1
    T MD 180

    AUF DB10
    L DB1.DBD8
    T DBD[MD180]

    Ist es überhaupt möglich den Zähler als "indirekten Adresswert" zunehmen?
    -Bzw. muss der Z1 Datentyp der gleiche sein wie MD180? (also DWord)

    Oder andersrum gefragt muss MD180 zwingend Dword sein, es beinhaltet ja nur die Adresse und keinen real wert?

  4. #4
    Registriert seit
    23.07.2009
    Ort
    Österreich
    Beiträge
    2.367
    Danke
    457
    Erhielt 696 Danke für 521 Beiträge

    Standard

    Zitat Zitat von Junge Beitrag anzeigen
    Zuerst habe ich ein DB10 mit einem Array[0..49] erstellt in Real.
    Dann dachte ich an so etwas:
    Code:
    AUF DB10
    
    L Z1
    SLD3
    LAR1
    T MD 180                                          //Dword- Pointer hinterlegt  
    
     L DB1.DBD8                                      //Realtyp- Signalwert
     T DBW[MD180]                                 //Wert soll das entsprechende Array im DB10 hinterlegt werden
    alternativ, Wenn ich es ganz einfach halte:

    Code:
          AUF   DB    10
     
          L    1
          SLD   3
          LAR1  
          T     MD   180                          //dword
          L     DB1.DBD    8                    //real
          T     DBW [MD   180]
    Du vermischt da ein wenig Äpfel mit Birnen.

    Das mit dem SLD3 kommt von Register-indirekter Adressierung, wogegen das L DBW[MD180] von einer anderen Type der indirekten Adressierung kommt (korrekter Name fällt mir grad nicht ein)

    In beiden Fällen musst du zuerst mal die Zieladresse korrekt ausrechnen.
    Dann kannst du auf eine der Varianten zurückgreifen.
    Code:
     L  #IndexNummer    //0-beginnend
     L  L#4            //Speicherbreite Real
     *D
     L  #DbOffset_Array    //Speicheradresse bei der das Array im DB beginnt.
     +D
     T  #DbAddr        //Byte-Adresse das gesuchten Elements im DB (am besten hier einen DINT-TEMP-Wert nehmen)
    
    
    //--------------------- Variante 1
        
     AUF DB 10        //DB öffnen
     L   DBD[#DbAddr]    //Datendoppelwort mit variable Adresse laden
    
    
    //--------------------- Variante 2 - Registerindirekte Adressierung (Zeiger)
    
    
    L   #DbAddr        //StartAdresse im DB
    SRD 3                   //Umwandeln in Pointer
    LAR1            //In Adressregister laden
    L DBD[AR1,p#0.0]        //Wert über Adressregister laden
    
    
    //--------------------- Variante 3 - Einen kleinen SCL-FC schreiben und mit variablen Array-Indizes arbeiten
    Geändert von RONIN (05.08.2015 um 18:18 Uhr)
    If at first you don't succeed, you're not Van Damme!
    ... or maybe using TIA!

  5. #5
    Registriert seit
    23.07.2009
    Ort
    Österreich
    Beiträge
    2.367
    Danke
    457
    Erhielt 696 Danke für 521 Beiträge

    Beitrag

    Zitat Zitat von Junge Beitrag anzeigen
    Ist es überhaupt möglich den Zähler als "indirekten Adresswert" zunehmen?
    Wenn dein Zähler so zählt dann ja:
    Startadresse im DB + 0
    Startadresse im DB + 4
    Startadresse im DB + 8
    etc.

    Mit einem Z1 alleine schaffst du das natürlich nicht. Siehe die Berechnung im vorigen Beirag

    Das hier hat auch ein Problem....
    Zitat Zitat von Junge Beitrag anzeigen
    Code:
    AUF DB10        ​//Hier öffnest du den DB10
    L DB1.DBD8      //Hier wird aber der DB1 automatisch mitgeöffnet    
    T DBD[MD180]​    //Hier lädst du also aus DB1 das Doppelwort mit der Byteadresse die in MD180 steht, welche bedingt durch das SLD3 wahrscheinlich Blödsinn ist.    
    Das letztere kannst du nur umgehen in dem zu entweder zwischendrin keinen anderern DB aufrufst oder Temp/Merkerwerte nimmst.
    Code:
    L DB1.DBD8 
    AUF DB10           //Korrekten DB erst kurz vor indirektem Zugriff öffnen
    T DBD[MD180]​ 
    
    oder
    
    L DB1.DBD8 
    T TEMP-Wert           //TEMP-Wert verwenden
    
    AUF DB10
    L TEMP-Wert           //TEMP oder Merkerwerte beeinflussen nicht den geöffneten DB im DB-Register
    T DBD[MD180]​
    Geändert von RONIN (05.08.2015 um 18:18 Uhr)
    If at first you don't succeed, you're not Van Damme!
    ... or maybe using TIA!

  6. #6
    Avatar von Junge
    Junge ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    13.11.2014
    Ort
    Paderborn
    Beiträge
    194
    Danke
    15
    Erhielt 13 Danke für 12 Beiträge

    Standard

    OH! Danke!! ich glaube das wird mir schon viel weiterhelfen! Kann es leider erst morgen auf der Arbeit ausprobieren.
    @Ronin:

    Aber ich hab immer noch ein paar Fragen

    Da ich ja etwas auf den DB schreiben möchte wäre es dann so richtig?

    L #IndexNummer //0-beginnend
    L L#4 //Speicherbreite Real Was bedeutet L#4, das sehe ich zum ersten mal.
    *D
    L #DbOffset_Array //Speicheradresse bei der das Array im DB beginnt. Also Bspw. L 0 oder L 40, wenn das array bei DB10.DbD0 oder DB10.DbD10 beginnt?
    +D
    T #DbAddr //Byte-Adresse das gesuchten Elements im DB (am besten hier einen DINT-TEMP-Wert nehmen)


    AUF DB 10 //DB öffnen
    L DB1.DBD8 // Der Datenwert in Real der abespeichert werden soll
    T DBD[#DbAddr] //Datendoppelwort mit variable Adresse laden

    So müsste es doch dann eigentlich funktionieren?!
    Geändert von Junge (05.08.2015 um 18:34 Uhr)

  7. #7
    Registriert seit
    23.07.2009
    Ort
    Österreich
    Beiträge
    2.367
    Danke
    457
    Erhielt 696 Danke für 521 Beiträge

    Standard

    Zu Rot 1:
    4 ist eine Integer-Konstante, L#4 ist einen Doppelintegerkonstante.
    L 500000 geht nicht (INT zu klein)
    L L#500000 geht schon

    Sowohl Variante 1 (L DBD[DINT-Variable]) als auch Variante 2 (SLD DINT-Variable) erfordern Doppelinteger.
    Durch das verwenden der korrekten Konstanten und Befehle (*D, +D) bleibt man immer schön im selben Format.

    Zu Rot 2:
    Ja Korrekt.
    Unten muss einfach die richtige Adresse rauskommen.
    Beispiel: Dein Array[0..49] startet bei DBD10 und du willst auf Array[10], dann lautet die Adresse dieses Reals im DB ja 50.
    Genau das muss dann auch in #DbAddr stehen. Ist eigentlich nur einfache Mathematik

    Zu Rot 3:
    Problem. Lies dir Beitrag 5 nochmal durch.
    If at first you don't succeed, you're not Van Damme!
    ... or maybe using TIA!

  8. Folgender Benutzer sagt Danke zu RONIN für den nützlichen Beitrag:

    Junge (05.08.2015)

  9. #8
    Avatar von Junge
    Junge ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    13.11.2014
    Ort
    Paderborn
    Beiträge
    194
    Danke
    15
    Erhielt 13 Danke für 12 Beiträge

    Standard

    Ja klar,....der Tag war schon lang ^^ gut das du mich nochmal drauf hinweist.

    Zu Rot3: wäre es dann entsprechend

    L DB1.DBD8 // Der Datenwert in Real der abespeichert werden soll
    AUF DB 10 //DB öffnen
    T DBD[#DbAddr] //Datendoppelwort mit variable Adresse laden

    Danke nochmal für die vielen Tipps und den guten Erklärungen, hat mir schon viel weitergeholfen.








    ...Hier nochmal meine eigene Zusammenfassung. Vllt hilft es in Zukunft auch nochmal anderen! Kommentare sind von mir..ich übernehme dafür aber keine Verantwortung

    Aufgabe war: einen REAL Datenwert alle 100ms in ein Array in einem Datenbaustein (DB10) abzulegen, wenn das Startsignal E136.0 da ist.

    DB10 ist erstellt. Array im DB10 auch erstellt mit Array[0..49] Datentyp REAL
    Das heißt es gibt jetzt im DB10:
    DB10.DBD0
    DB10.DBD4
    DB10.DBD8
    ...
    ..
    .
    Code:
                    UN E136.0                   //Wenn kein Startsignal, Resete alle Laufvariablen
                    SPB M001
    
                    L Z1                            //Zähler Z1 startet, wenn E136.0 da ist und wird all 100ms vorwärts  gezählt
                    LMW2                         // MW2 Hilfsmerke
                    >I
                    =M0.2                        //Wenn M0.2=1, dann wurde Z1 hochgezählt
        
                    UN M0.2                     // Wenn Zähler noch nicht erhöht springe zu NOP 0
                    SPB M002
    
                    LZ1                            //Z1 und MW2 abgleichen
                    T MW2
    
                    L Z1                           //Bsp. Z1=1
                    L L#4                         // L4 ist eine Integer-Konstante, L#4 ist einen Doppelintegerkonstante.
                    *D                             // Datenformat muss beibehalten werden.
                    L 0                             //Offsetwert (hier NULL, aber ich brauch den später noch), wenn zB.  Array im DB nicht bei DB10.DBD0 sondern bei zB. DB10.DB4  anfängt-> L 4
                    +D
                    SLD 3
                    T #DB_Addr               //  #DB_Addr. ist eine Temporäre Variable wird im FC Baustein in der oberen  Leiste eingetragen und gilt nur für diesen Baustein (Quasi  lokale Variable) In dieser steht jetzt die Datenbausteinadresse!
        
                    L DB1.DBD8                // Hier steht der zu speicherne Messwert
                    AUF DB10                  //Ruft den DB10 auf, somit weiss der #DB_Addr auf welchen DB sich die  Adresse beziehen soll
                    T DBD[#DA_Addr]      //  Tranferiert den Wert aus DB1.DBD8 in den DB10 mit der  Datenbausteinadresse aus #DA_Addr
    
    M001:       L 0
                    T MW2
    
    M002: NOP 0
    Geändert von Junge (06.08.2015 um 10:09 Uhr)

  10. #9
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.316
    Danke
    932
    Erhielt 3.331 Danke für 2.689 Beiträge

    Standard

    Auch bei der speicherindirekten Adressierung muß die Adresse im Doppelwordformat als Bitadresse angegeben werden. Nach dem "+D" fehlt noch ein "SLD 3" (oder mit 8 multiplizieren)
    Code:
    L Z1 //Bsp. Z1=1 
    L L#4 // L4 ist eine Integer-Konstante, L#4 ist einen Doppelintegerkonstante. 
    *D // Datenformat muss beibehalten werden. 
    L 0 //Offsetwert (hier NULL, aber ich brauch den später noch), wenn zB. Array im DB nicht bei DB10.DBD0 sondern bei zB. DB10.DB4 anfängt-> L 4 
    +D 
    SLD 3 // Byteoffset --> P#x.0
    T #DB_Addr // #DB_Addr. ist eine Temporäre Variable wird im FC Baustein in der oberen Leiste eingetragen und gilt nur für diesen Baustein (Quasi lokale Variable) In dieser steht jetzt die Datenbausteinadresse! 
    
    L DB1.DBD8 // Hier steht der zu speicherne Messwert 
    AUF DB10 //Ruft den DB10 auf, somit weiss der #DB_Addr auf welchen DB sich die Adresse beziehen soll 
    T DBD[#DA_Addr] // Tranferiert den Wert aus DB1.DBD8 in den DB10 mit der Datenbausteinadresse aus #DA_Addr
    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  11. #10
    Avatar von Junge
    Junge ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    13.11.2014
    Ort
    Paderborn
    Beiträge
    194
    Danke
    15
    Erhielt 13 Danke für 12 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ja stimmt, hab es heute morgen auf der Arbeit, zum Glück rechtzeitig noch gemerkt

    Werde es ín meiner Zusammenfassung korrigieren!

Ähnliche Themen

  1. indirekte Adressierung
    Von schneijo im Forum Simatic
    Antworten: 7
    Letzter Beitrag: 22.10.2012, 14:42
  2. Indirekte Adressierung
    Von Bensen83 im Forum Simatic
    Antworten: 34
    Letzter Beitrag: 26.01.2010, 11:33
  3. Indirekte Adressierung
    Von Rainer im Forum Simatic
    Antworten: 12
    Letzter Beitrag: 21.05.2008, 15:07
  4. Indirekte Adressierung !
    Von max1de im Forum Simatic
    Antworten: 7
    Letzter Beitrag: 27.02.2007, 18:18
  5. Indirekte Adressierung
    Von Raab im Forum Simatic
    Antworten: 1
    Letzter Beitrag: 20.12.2003, 12:17

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •