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

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: indirekte Adressierung und Pointer ??????????????

  1. #1
    Mathias W. Gast

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Leute, brauche ein Schieberegister das folgende ersetzt und Flexibler zu Handhaben ist!


    Netzwerk 1:
    U M 0.0 // SPS-Taktmerker
    FP M 10.0 // Pos-Flanke
    = M 11.0 // Flankenimpulsmerker

    Netzwerk 2:
    U M 11.0
    SPBN M001

    AUF DB 10
    L DBB 4
    T DBB 5
    L DBB 3
    T DBB 4
    L DBB 2
    T DBB 3
    L DBB 1
    T DBB 2
    L DBB 0
    T DBB 1

    L EB 1
    T DBB 0

    M001: NOP 0

    Dieser Code funktioniert ja, aber da ich so circa 100 Impulse land die Daten im DB erhalten muß ist das verdammt viel Schreibarbeit und das ganze ist äußerst unflexsibel.

    Ich habe dieses ausprobiert, aber es funktioniert nicht!!!!

    FC irgendwas

    Netzwerk 1:

    AUF DB [#DB_Nummer] // Die DB-Nr wird beim Aufruf des FC's an die
    // Lokalvariable übergeben (funktioniert noch)

    L #Takte // hier wird die Länge Schieberegisters erstellt
    SCHL: T #Sch_Zaehler

    L DBB [#DB_Nr_Lesen] // z.B. Byte 9 einlesen
    T DBB [#DB_Nr_Schreiben] // und in Byte 10 ablegen, danach
    // Byte 8 einlesen und in Byte
    L #DB_Nr_Lesen // 9 ablegen, usw.
    + -1 // "DB_Nr_Lesen"
    L #DB_Nr_Schreiben // und "DN_Nr_Schreiben" sind Lokal-
    + -1 // Variablen vom Typ DWORD

    L #Sch_Zaehler
    LOOP SCHL

    NOP 0
    L #Ein_Byte // Nach jedem Schleifendurchlauf werden die neuen
    T DBB 0 // Informationen im DB XX.DBB 0 gespeichert

    Wenn ich den Code in die SPS (CPU 313C) dann geht die CPU in Stop und der Fehler liegt irgendwo bei der Zeile:

    L DBB [#DB_Nr_Lesen] und
    T DBB [#DB_Nr_Schreiben].

    wenn ich dort direkte Adressen eingebe dann läufts! Was aber dann kein Schieberegister mehr ist!

    Kann mir jemand helfen bei der indirekten Adressierung, aber bitte ganz langsam, zum mitmeißeln????

    Gruß Mathias
    Zitieren Zitieren Gelöst: indirekte Adressierung und Pointer ??????????????  

  2. "Also DB-Nr muss nicht angepasst werden und wenn man für sowas nen FB mit IDB verwendet das is glatte Verschwendung. Mit den temporären Variablen das klappt sofern sie immer beschrieben werden. Es passiert ja alles in einem SPS-Zyklus und es muss nichts gemerkt werden. Die Verwendung des Adressregisters ist in dem Fall nicht nötig, da es alles über bereichsinterne indirekte Adressierung erfolgt.

    MfG
    André Räppel"


  3. #2
    Registriert seit
    30.08.2003
    Beiträge
    2.196
    Danke
    30
    Erhielt 258 Danke für 229 Beiträge

    Standard

    Na hallo, müsstest schon mal den gesamten Baustein mit Schnittstelle hier reinstellen oder mir mailen.

    MfG
    André Räppel
    Zitieren Zitieren Problem  

  4. Folgender Benutzer sagt Danke zu sps-concept für den nützlichen Beitrag:

    SIGGI (22.02.2009)

  5. #3
    Anonymous Gast

    Standard

    Sorry, man kann schon mal was vergessen, oder????

    ********************************************************
    OB 1

    Netzwerk 1:
    U "Taktmerker7"
    FP "Flankenmerker 1"
    = "Taktflanke"

    Netzwerk 2:
    U "Taktflanke"
    SPBN M004

    CALL FC96
    Takte :=100
    Ein_Byte:=EB1
    DB_Nr :=96

    M004: NOP 0
    *****************************************************
    FC 96:
    Deklarationsteil:
    IN:
    Takte = Integer
    Ein_Byte = Byte
    DB_Nr = Integer
    OUT:
    IN/OUT:
    TEMP:
    Sch_Zaehler = Integer
    DB_Nummer = Integer
    Zahl1 = DWord
    Zahl2 = DWord

    Netzwerk 1:
    L #DB_Nr
    T #DB_Nummer

    L #Takte
    T #Zahl1

    L #Zahl1
    + -1
    T #Zahl2

    Netzwerk 2:
    AUF DB [#DB_Nummer]

    L #Takte
    SCHL: T #Sch_Zaehler
    L #Zahl1
    SLW 3

    L #Zahl2
    SLW 3

    L DBB [#Zahl2]
    T DBB [#Zahl1]

    L #Zahl1
    + -1
    T #Zahl1

    L #Zahl2
    + -1
    T #Zahl2

    L #Sch_Zaehler
    LOOP SCHL

    NOP 0
    L #Ein_Byte
    T DBB 0

    Ich hoffe dieses Beispiel sagt etwas mehr aus! wenn nicht dann fragt mich ruhig nochmal! Brauche dringend hilfe!!!!

  6. #4
    Registriert seit
    30.08.2003
    Beiträge
    2.196
    Danke
    30
    Erhielt 258 Danke für 229 Beiträge

    Standard

    also erstmal solltest du SLD anstatt SLW benutzen, sowie + L#-1. Sollte aber bei 100 Bytes noch keine Probleme bereiten. Den Rest probier ich mal.

    MfG
    André Räppel
    Zitieren Zitieren Problem  

  7. Folgender Benutzer sagt Danke zu sps-concept für den nützlichen Beitrag:

    SIGGI (22.02.2009)

  8. #5
    Registriert seit
    30.08.2003
    Beiträge
    2.196
    Danke
    30
    Erhielt 258 Danke für 229 Beiträge

    Standard

    so, das müsste jetzt so gehen. Die SLW die sind ja nur im Akku gelandet und nich auf der Variable. Kannst aber in deinem Fall direkt vom Schleifenzähler abhängig machen da du ja vom grösseren Wert zum kleineren gehst. Hier mal der Lösungsansatz. Nachvollziehen und Verschönern musste ihn selber. Bedenke auch solche Sachen mit Datenformaten.

    Code:
    FUNCTION FC 96 : VOID
    TITLE =
    AUTHOR : ARaeppel
    VERSION : 1.0
    
    
    VAR_INPUT
      Takte : INT ;	
      Ein_Byte : BYTE ;	
      DB_Nr : INT ;	
    END_VAR
    VAR_TEMP
      Sch_Zaehler : INT ;	
      DB_Nummer : INT ;	
      Adr_Quelle : DWORD ;	
      Adr_Ziel : DWORD ;	
    END_VAR
    BEGIN
    NETWORK
    TITLE =
    
          L     #DB_Nr; 
          T     #DB_Nummer; 
    NETWORK
    TITLE =
    
          AUF   DB [#DB_Nummer]; 
    
          L     #Takte; 
    SCHL: T     #Sch_Zaehler; 
    
    // Schleifenzähler im Akku
          SLD   3; 
          T     #Adr_Ziel; 
    
          L     #Sch_Zaehler; 
          +     L#-1; 
          SLD   3; 
          T     #Adr_Quelle; 
    
    
          L     DBB [#Adr_Quelle]; 
          T     DBB [#Adr_Ziel]; 
    
    
          L     #Sch_Zaehler; 
          LOOP  SCHL; 
    
    
          L     #Ein_Byte; 
          T     DBB    0; 
    END_FUNCTION
    MfG
    André Räppel
    Zitieren Zitieren Lösung  

  9. Folgender Benutzer sagt Danke zu sps-concept für den nützlichen Beitrag:

    SIGGI (22.02.2009)

  10. #6
    Registriert seit
    16.06.2003
    Ort
    88356 Ostrach
    Beiträge
    4.811
    Danke
    1.231
    Erhielt 1.101 Danke für 527 Beiträge

    Standard

    ich habe mir jetzt nicht viel zeit genommen, und den code auch nicht ganz
    durchgeschaut, aber bist du sicher das das mit den temporären lokalvariblen von fc&s geht?
    mit den dingern sollte man vorsichtig sein, besser nen fb + idb anlegen und statische lokalvariablen benutzen.

    muss die db-nr nicht auch mit slw angepasst werden?

    bei einem schieberegister ist es einfacher mit den adressregistern zu arbeiten.


    also

    #Pointer
    slw 3

    LAR1

    AUF DB96

    L #Wert_1
    T DBW [AR1,P#0.0]

    L #Wert_2
    T DBW [AR1,P#2.0]


    wenn der Pointer=4 ist dann wird wert_1 in dbw4 eingetragen und wert_2 in dbw6

  11. Folgender Benutzer sagt Danke zu Markus für den nützlichen Beitrag:

    SIGGI (22.02.2009)

  12. #7
    Registriert seit
    30.08.2003
    Beiträge
    2.196
    Danke
    30
    Erhielt 258 Danke für 229 Beiträge

    Standard

    Also DB-Nr muss nicht angepasst werden und wenn man für sowas nen FB mit IDB verwendet das is glatte Verschwendung. Mit den temporären Variablen das klappt sofern sie immer beschrieben werden. Es passiert ja alles in einem SPS-Zyklus und es muss nichts gemerkt werden. Die Verwendung des Adressregisters ist in dem Fall nicht nötig, da es alles über bereichsinterne indirekte Adressierung erfolgt.

    MfG
    André Räppel
    Zitieren Zitieren Code  

  13. Folgender Benutzer sagt Danke zu sps-concept für den nützlichen Beitrag:

    SIGGI (22.02.2009)

  14. #8
    Mathias W. Gast

    Standard

    Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke, Danke,
    Du rettest einem Kleingeist das Leben, das Problem ist immer:

    Wie sollst du was finden, wenn Du nicht weißt wonach Du suchst!!!!!

    Danke, alles funktioniert bestens!!!

    Gruß Mathias

    P.S.: über den Vorschlag von Markus denke ich noch nach, es wird wahrscheinlich so kommen das das Ding in einen FB kommt und mit einem Instanz-DB versorgt wird, aber das weiss ich noch nicht!
    Zitieren Zitieren Es funktioniert!!!!  

  15. #9
    Anonymous Gast

    Standard

    Hallo Mathias
    Bin auch der Meinung, dass für diese Aufgabe eine Funktion ausreicht.

    Obwohl Du schon eine Lösung gefunden hast, poste ich hier noch meine beiden Lösungsvorschläge.

    Die erste Variante arbeitet ohne Adressregister (AR1 oder AR2).

    Code:
    FUNCTION FC1 : VOID
    TITLE =Schieberegister mit speicherindirekter Adressierung
    
    VAR_INPUT
      DB_Nr : INT ;	//DB-Nr. des Schieberegisters
      Takte : INT ;	//Länge des Schieberegister 
      Ein_Byte : BYTE ;	//Akt.Wert
    END_VAR
    
    VAR_TEMP
      DB_Nummer : INT ;	//Temp.Variable für DB-Nr.
      Sch_Zaehler : INT ;	//Akt.Schleifenzähler
      Zeiger_lesen : DWORD ;	//Lesezeiger für die speicherindirekte Adressierung
      Zeiger_schreiben : DWORD ;	//Schreibzeiger für die speicherindirekte Adressierung
    END_VAR
    
    BEGIN
    NETWORK
    TITLE =DB aufschlagen
    //Parameter können in einem FC nicht direkt für die Speicherindirekte 
    //Adressierung verwendet werden, darum wird die DB-Nr. zuerst in eine 
    //Temp.Variable kopiert.
          L     #DB_Nr; 
          T     #DB_Nummer; 
          AUF   DB [#DB_Nummer]; 
    
    NETWORK
    TITLE =Prüfen ob die Länge des Schieberegisters  1 ist
    //Hier wird als Beispiel einer der möglichen Sonderfälle geprüft. 
    //Im Baustein könnte z.B. noch folgendes gerprüft werden:
    //- DB-Nr. gültig
    //- Länge des DB gültig
          L     #Takte; 
          L     1; 
          ==I   ; 
          SPB   Lae1; 
    
    NETWORK
    TITLE =Schleife für Schieberegister
    
    //letzte Byteadresse im Schieberegister berechnen
          L     #Takte; 
          +     L#-1; 
          SLD   3; 
          T     #Zeiger_schreiben; 
    
    //zweitletzte Byteadresse im Schieberegister berechnen
          L     P#1.0; //Im Akku steht 00000000_00000000_00000000_00001000
          -D    ; 
          T     #Zeiger_lesen; 
    
          L     #Takte; 
          +     L#-1; 
    SCHL: T     #Sch_Zaehler; 
    
          L     DBB [#Zeiger_lesen]; 
          T     DBB [#Zeiger_schreiben]; 
    
    //Lesezeiger wird zum Schreibzeiger 
          L     #Zeiger_lesen; 
          T     #Zeiger_schreiben; 
    
    //Neuer Lesezeiger berechnen -> um 1 Byte verkleinern
          L     P#1.0; 
          -D    ; 
          T     #Zeiger_lesen; 
    
          L     #Sch_Zaehler; 
          LOOP  SCHL; 
    
    NETWORK
    TITLE =Akt.Wert in Schieberegister schreiben
    
    Lae1: L     #Ein_Byte; 
          T     DBB    0; 
    END_FUNCTION
    In der zweiten Variante wird das AR1 verwendet.

    Code:
    FUNCTION FC 2 : VOID
    TITLE =Schieberegister mit registerindirekter Adressierung
    
    VAR_INPUT
      DB_Nr : INT ;	//DB-Nr. des Schieberegisters
      Takte : INT ;	//Länge des Schieberegister 
      Ein_Byte : BYTE ;	//Akt.Wert
    END_VAR
    
    VAR_TEMP
      DB_Nummer : INT ;	//Temp.Variable für DB-Nr.
    END_VAR
    
    BEGIN
    NETWORK
    TITLE =DB aufschlagen
    //Parameter können in einem FC nicht direkt für die Speicherindirekte 
    //Adressierung verwendet werden, darum wird die DB-Nr. zuerst in eine 
    //Temp.Variable kopiert.
          L     #DB_Nr; 
          T     #DB_Nummer; 
          AUF   DB [#DB_Nummer]; 
    
    NETWORK
    TITLE =Prüfen ob die Länge des Schieberegisters  1 ist
    //Hier wird als Beispiel einer der möglichen Sonderfälle geprüft. 
    //Im Baustein könnte z.B. noch folgendes gerprüft werden:
    //- DB-Nr. gültig
    //- Länge des DB gültig
          L     1; 
          L     #Takte; 
          ==I   ; 
          SPB   Lae1; 
    
    NETWORK
    TITLE =Schleife für Schieberegister
    
    //zweitletzte Byteadresse im Schieberegister berechnen
          PUSH  ; //Anzahl Takte wird später noch einmal benötigt -> Kopie in Akku2
          +     L#-2; 
          SLD   3; 
          LAR1  ; //-> Zeiger in Akku1 wird in das AR1 geladen
    
          TAK   ; //Anzahl Takte steht wieder im Akku1
          +     L#-1; //Anzahl Schleifendurchläufe berechnen
    SCHL: L     DBB [AR1,P#0.0]; 
          T     DBB [AR1,P#1.0]; //Offset auf die nächste Byteadresse
    
          TAK   ; //Schleifezähler steht wieder im Akku1
    
    //AR1 muss über den Akku1 um 1 Byte verkleinert werden
          TAR1  ; //AR1 in Akku1 schreiben (Schleifezähler steht im Akku2)
          +     L#-8; //Akku1 um 1 Byte dekrementieren (Wert 8 steht für 1000 -> P#1.0)
          LAR1  ; //Akku1 wieder in AR1
    
          TAK   ; //Schleifezähler steht wieder im Akku1
          LOOP  SCHL; 
    
    NETWORK
    TITLE =Akt.Wert in Schieberegister schreiben
    Lae1: L     #Ein_Byte; 
          T     DBB    0; 
    
    END_FUNCTION
    PS: Kennst Du die Möglichkeit solche Programme im HALT-Modus (Debugmodus) zu beobachten?

  16. #10
    Mathias W. Gast

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo, leider kenne ich diese möglich nicht, wäre sehr interresant dies zu erfahren.

    Gruß Mathias
    Zitieren Zitieren Leider nein  

Ähnliche Themen

  1. Indirekte Adressierung
    Von Bensen83 im Forum Simatic
    Antworten: 34
    Letzter Beitrag: 26.01.2010, 11:33
  2. Indirekte Adressierung über einen ANY Pointer
    Von sventek im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 11.12.2009, 06:33
  3. cpu stop indirekte adressierung pointer
    Von falk.jaeger im Forum Simatic
    Antworten: 17
    Letzter Beitrag: 23.02.2009, 07:22
  4. Indirekte-Adressierung
    Von johnij im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 14.02.2008, 14:32
  5. Indirekte Adressierung
    Von wusel220983 im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 18.05.2007, 18:19

Lesezeichen

Berechtigungen

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