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

Seite 3 von 5 ErsteErste 12345 LetzteLetzte
Ergebnis 21 bis 30 von 41

Thema: Scheife - kleines Prog.

  1. #21
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.182
    Danke
    923
    Erhielt 3.289 Danke für 2.658 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Limette,

    Du hast anscheinend aus dem Codeschnipsel einen parametrierbaren FB gemacht. Zeige uns doch mal die Aufrufschnittstelle Deines FB.

    Mit LAR1 P##Eingang lädst Du die Adresse des FB-Eingangsparameters und NICHT die Adresse, die Du beim Aufruf übergibst. Du müßtest die Bereichs-Anfangsadresse und die Bereichs-Endeadresse als POINTER übergeben, dann kannst Du beim FB-Aufruf E4.0 und E6.5 dranschreiben.

    Den Instanz-DB brauchst Du nicht öffnen, der wird beim FB-Aufruf automatisch als DI geöffnen. LAR2 P#DIX 7.0 solltest Du noch zu einem symbolischen Zugriff umformulieren.

    Ich habe jetzt leider nicht mehr Zeit.

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  2. #22
    Registriert seit
    08.10.2009
    Ort
    Südpfalz
    Beiträge
    273
    Danke
    43
    Erhielt 54 Danke für 47 Beiträge

    Standard

    Zitat Zitat von Limette Beitrag anzeigen
    [CODE]

    bei
    greife ich ja auf den instanz db zu. kann es sein dass ich den db zuerst laden muss ?
    Der IDB muss natürlich mit entsprechender Länge in der CPU vorhanden sein.

    Was sagt den der Diagnosespeicher bei CPU-STOP?

    Gruß Roland
    Nicht Mensch, nicht Tier: Programmierer halt ...

  3. #23
    Limette ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    25.10.2010
    Beiträge
    239
    Danke
    107
    Erhielt 2 Danke für 2 Beiträge

    Standard

    Zitat Zitat von Der Pfälzer Beitrag anzeigen
    Der IDB muss natürlich mit entsprechender Länge in der CPU vorhanden sein.

    Was sagt den der Diagnosespeicher bei CPU-STOP?

    Gruß Roland
    ok, ich kopier ihn einfach mal rein. vllt kannst du damit was anfangen.


    Ereignis 1 von 2: Ereignis-ID 16# 4562
    STOP durch Programmierfehler (OB nicht geladen oder nicht möglich, bzw. kein FRB vorhanden )
    FB-Nummer: 1
    Bausteinadresse: 20
    Bisheriger Betriebszustand: RUN
    Angeforderter Betriebszustand: STOP (intern)
    interner Fehler, kommendes Ereignis
    16:43:37.986 18.03.2011


    Ereignis 2 von 2: Ereignis-ID 16# 2523
    Bereichslängenfehler beim Schreiben
    Instanz-DB , Bitzugriff, Zugriffsadresse: 7
    Angeforderter OB: Programmierfehler-OB (OB 121)
    OB nicht vorhanden oder gesperrt oder nicht startbar im aktuellen Betriebszustand
    interner Fehler, kommendes Ereignis
    16:43:37.982 18.03.2011

  4. #24
    Limette ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    25.10.2010
    Beiträge
    239
    Danke
    107
    Erhielt 2 Danke für 2 Beiträge

    Standard

    Zitat Zitat von PN/DP Beitrag anzeigen
    Hallo Limette,

    Du hast anscheinend aus dem Codeschnipsel einen parametrierbaren FB gemacht. Zeige uns doch mal die Aufrufschnittstelle Deines FB.

    Mit LAR1 P##Eingang lädst Du die Adresse des FB-Eingangsparameters und NICHT die Adresse, die Du beim Aufruf übergibst. Du müßtest die Bereichs-Anfangsadresse und die Bereichs-Endeadresse als POINTER übergeben, dann kannst Du beim FB-Aufruf E4.0 und E6.5 dranschreiben.

    Den Instanz-DB brauchst Du nicht öffnen, der wird beim FB-Aufruf automatisch als DI geöffnen. LAR2 P#DIX 7.0 solltest Du noch zu einem symbolischen Zugriff umformulieren.

    Ich habe jetzt leider nicht mehr Zeit.


    Harald
    wie ich sehe habe ich noch ein wenig nachholbedarf. so richtig habe ich dich nicht verstanden.
    was wohl aber dann nicht geht ist

    Code:
    LAR1 P##Eingang
    "Eingang" in der Schnittstelle als Integer oder Dword Eingang zu bestimmen und ihm dann einfach im OB z.b. 4 bzw. DW#16#4 zu zuweisen.

  5. #25
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.182
    Danke
    923
    Erhielt 3.289 Danke für 2.658 Beiträge

    Standard

    Tscha, die registerindirekte Adressierung ist am Anfang ziemlich schwer zu meistern.
    Zeig doch mal die komplette Deklaration Deines FB, dann kann ich Dir das für Deinen FB passend umschreiben.
    Muß Dein FB multiinstanz-fähig sein?

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  6. #26
    Limette ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    25.10.2010
    Beiträge
    239
    Danke
    107
    Erhielt 2 Danke für 2 Beiträge

    Standard

    Zitat Zitat von PN/DP Beitrag anzeigen
    Tscha, die registerindirekte Adressierung ist am Anfang ziemlich schwer zu meistern.
    Zeig doch mal die komplette Deklaration Deines FB, dann kann ich Dir das für Deinen FB passend umschreiben.
    Muß Dein FB multiinstanz-fähig sein?

    Harald

    Herzlichen Dank für deine Mühe !

    ich umreiße mal kurz mein gesamtes vorhaben.
    ich habe 10 fbs mit gleicher logik die nur verschieden Eingänge haben (je 8 -13 Eingänge von DP, max. 2 byte groß), die dann 4 weitere FBs (Ausgänge) aufrufen sollen.
    ich dachte es wäre das beste per Schleife die Eingänge eines fbs abzufragen, sie dann "intern" zu einer Logik verarbeiten und dann die entsprechenden Ausgänge zu setzen. Den code könnte ich ja dann praktisch 10 mal anwenden, müsste nur im OB die entsprechenden Eingangsadressen angeben.
    Was mir noch nicht ganz klar ist, warum der code den du geschrieben hast nicht funktioniert hat. Ich hab noch ein wenig rumprobiert und bin mir sicher dass die sps bei
    Code:
    LAR2  P#DIX 7.0
    auf jeden fall in "Stop" gegangen ist.

  7. #27
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.182
    Danke
    923
    Erhielt 3.289 Danke für 2.658 Beiträge

    Standard

    Zitat Zitat von Limette Beitrag anzeigen
    Ich hab noch ein wenig rumprobiert und bin mir sicher dass die sps bei
    Code:
    LAR2  P#DIX 7.0
    auf jeden fall in "Stop" gegangen ist.
    Bei dieser Operation ist die CPU GARANTIERT NICHT in Stop gegangen.
    Da wird nur das Adressregister AR2 mit irgendeiner Adresse geladen, es ist noch nicht einmal ein Speicherzugriff.

    Die CPU geht aber z.B. bei = [AR2,P#0.0] in Stop, wenn Dein Instanz-DB nicht mindestens 8 Byte lang ist (und kein OB121 in der CPU ist).

    Die genaue Stop-Stelle erfährt man aus dem Diagnosepuffer der CPU, da ist direkt vor (unter) dem Eintrag "STOP durch Programmierfehler" der Eintrag mit der Fehlerursache, bei Dir: "Bereichslängenfehler beim Schreiben". Den Eintrag markierst Du und liest Dir die Details zum Ereignis durch.
    Ereignis 2 von 2: Ereignis-ID 16# 2523
    Bereichslängenfehler beim Schreiben
    Instanz-DB , Bitzugriff, Zugriffsadresse: 7
    Das bedeutet: Der Instanz-DB in der CPU hat keine Adresse 7, er ist also zu kurz oder garnicht geladen.
    Die Operation war ein Bit-Schreibzugriff: S, R oder =.

    Mit dem Button "Baustein öffnen" springt Step7 dann genau zu der Zeile, die den Fehler verursacht hat.


    Zitat Zitat von Limette Beitrag anzeigen
    Was mir noch nicht ganz klar ist, warum der code den du geschrieben hast nicht funktioniert hat.
    Der Code, den ich geschrieben habe, der funktioniert.
    Es funktioniert nicht der Code, den Du daraus gemacht hast.
    Wie ich weiter oben schon schrieb: LAR2 P#DIX 7.0 solltest Du noch zu einem symbolischen Zugriff umformulieren.
    Der Bereich, wohin Du die Eingangszustände kopieren willst, beginnt bei Dir höchstwahrscheinlich nicht bei DBX7.0.
    Bei einem symbolischen Zugriff setzt der Editor automatisch die richtige Adresse ein.

    Ist es so schwer, hier endlich mal die Deklaration Deines FB zu posten? Du brauchst keine Betriebsgeheimnisse verraten, Deinen Code brauchen wir nicht, um die kurze Programmschleife passend zu Deinem FB umzuschreiben.
    Ohne Deine FB-Deklaration können wir Dir auch wieder nur Code geben, der andere Variablennamen als bei Dir hat, an dem Du dann "kaum" etwas ändern mußt - und bums - geht Deine CPU wieder in Stop.

    Wenn Du es selber hinbekommen willst, dann brauchst Du:
    - einen Eingangsparameter "Eingangsbereichsanfang" vom Typ POINTER
    - einen Eingangsparameter (oder TEMP/STAT-Variable) "Eingangsbereichsende" vom Typ POINTER
    - eine TEMP/STAT-Variable (oder Eingangsparameter) "Eingangsbereichslaenge" vom Typ INT (Dein FB muß ja auch wissen, ob er 8 oder 13 Eingänge verarbeiten muß)
    (die Länge kann der FB aus "Eingangsbereichsende" und "Eingangsbereichsanfang" selber berechnen oder das Ende aus Anfang und Länge)
    - ein ARRAY[0..15] OF BOOL im STAT-Bereich Deines FB, wohin die Eingangszustände kopiert werden
    - statt P#DIX 7.0 mußt Du den Name des Arrays einsetzen
    - falls Dein FB als Multi-Instanz genutzt wird, mußt Du den Multi-Instanz-Offset im AR2 beachten (besser: das AR2 auf jeden Fall dazuaddieren)
    - Beachte: zwischen dem LAR2 P#DIX 7.0 und dem LAR2 #tmpDW_AR2save kann nicht symbolisch auf Variablen der Instanz zugegriffen werden

    Viel Erfolg!
    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  8. Folgender Benutzer sagt Danke zu PN/DP für den nützlichen Beitrag:

    Limette (20.03.2011)

  9. #28
    Limette ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    25.10.2010
    Beiträge
    239
    Danke
    107
    Erhielt 2 Danke für 2 Beiträge

    Standard

    Hi,

    ich hab noch Verständnisfragen zu PN/DPs Code.

    Momentan lese ich ja 5 Bit, für DP-Eingänge ein (P#E5.0 - P#E5.5)und lade sie in den Instanzdatenbaustein ab Byte 15, also 15.0 bis 15.5, richtig ?

    wenn ja, wie kann ich jetzt damit arbeiten? wenn ich zum Beispiel P#E5.0 auf "1" setze, müsste ja im DI an Byte 15 auch eine "1" stehen, richtig ?

    wie könnte ich sowas abfragen ?


    Code:
    //Schleife für "krumme" Anfangs- oder Endeadressen
          TAR2  #tmpDW_AR2save              //AR2 sichern
          LAR1  P##AP1_Anfangsadresse       //Quell-Bereichsbeginn P#E5.0
          LAR2  P#DIX 15.0           //Ziel-Bereichsbeginn
    
    loop: U      [AR1,P#0.0]                //E[AR1] lesen
          =      [AR2,P#0.0]                //in DIX[AR2] übertragen
    
          +AR1  P#0.1                       //E-Pointer auf nächstes Bit
          TAR1  
          L     P##AP1_Endadresse           //Quell-Endadresse
          >D                                //überschritten? P#E5.5
          SPB   end
          +AR2  P#0.1                       //DIX-Pointer auf nächstes Bit
          SPA   loop                        //Schleife wiederholen
    
    end:  LAR2  #tmpDW_AR2save              //AR2 wiederherstellen

  10. #29
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.182
    Danke
    923
    Erhielt 3.289 Danke für 2.658 Beiträge

    Standard

    Es ist schon ein großer Unterschied, ob das Kopierprogramm mit festen Adressen oder mit parametrierbaren Adressen arbeitet! Es kommt zusätzlicher Code zur Parameterübernahme und Parameterprüfung dazu! Am kompliziertesten ist das korrekte Empfangen der als POINTER übergebenen Adressen der Kopierbereiche. Deshalb habe ich mal die Kopierschleife für den parametrierbaren Einsatz in FB erweitert. Die eigentliche Kopierschleife ändert sich fast nicht, es werden nur die festen Adressen durch Adress-Variablen ersetzt.

    Zunächst die Deklaration der verwendeten FB-IN-Parameter und FB-Variablen:
    Code:
    VAR_INPUT
      Anfangsadresse : POINTER ;	
      Endadresse : POINTER ;	
    END_VAR
    VAR
      stat_irgendwas : WORD ;	
      stat_E : ARRAY  [0 .. 15 ] OF BOOL  := FALSE; //hier liegen dann die eingelesenen Eingänge
      stat_nochwas : BOOL ;	
    END_VAR
    VAR_TEMP
      tmp_AR2save : DWORD ;	
      tmp_Anfangsadresse : DWORD ;	
      tmp_Endadresse : DWORD ;	
      tmp_Bereichslaenge : INT ; //Anzahl der eingelesenen Bits
      tmp_Bit : BOOL ;	
    END_VAR
    Hier nun der Programmcode (funktioniert NICHT mit Bits aus DB! Limette will ja nur Ex.y einlesen):
    Code:
          TAR2  #tmp_AR2save                //AR2 sichern, weil dies ein FB ist
    
    //Pointer auf Quellbereichsbeginn erstellen (das kann hier kein DB-Bereich sein!)
          LAR1  P##Anfangsadresse           //Adresse des IN-Parameters in der Grund-Instanz
          TAR2                              //eventueller Multiinstanz-Offset
          +AR1                              //Pointer auf IN-Parameter Quell-Bereichsbeginn
          L     D [AR1,P#2.0]               //nur Speicherbereichsadresse des übergebenen POINTER
          T     #tmp_Anfangsadresse
    //**      LAR1                              //(zum Beobachten)
    
    //Sicherstellen, daß Endadresse im selben Speicherbereich wie Anfangsadresse ist
    //und im Bereich Anfangsadresse ... Anfangsadresse+15 ist (begrenzte Array-Größe!)
          LAR1  P##Endadresse               //Adresse des IN-Parameters in der Grund-Instanz
          TAR2                              //eventueller Multiinstanz-Offset
          +AR1                              //Pointer auf IN-Parameter Quell-Endadresse
          L     D [AR1,P#2.0]               //nur Speicherbereichsadresse des übergebenen POINTER
    //**      LAR1                              //(zum Beobachten)
    
          L     #tmp_Anfangsadresse         //Akku1: Anfangsadresse / Akku2: Endadresse
          -D                                //Endadresse - Anfangsadresse = Bereichslaenge-1
          SPPZ  ckmx                        //OK, Endadresse >= Anfangsadresse
          L     0                           //Endadresse < Anfangsadresse! nur 1 Bit kopieren
    ckmx: L     15                          //maximale Bereichslänge-1
          >D    
          SPB   cead                        //Endadresse unzulässig -> 15 übernehmen
          POP                               //ursprüngliche Breichslaenge-1 oder 0 übernehmen
    cead: PUSH                              //( für S7-400 und PLCSIM: Akku2 = Akku1 = Bereichslaenge-1 )  
          PUSH                              //( für S7-400 und PLCSIM: Akku3 = Akku2 = Akku1 )  
          L     #tmp_Anfangsadresse         //Akku1: A.adr | Akku2: B.laenge-1 | (Akku3: B.laenge-1)
          +D                                //( S7-400 und PLCSIM: Akku2:=Akku3! )
          T     #tmp_Endadresse
    //**      LAR1                              //(zum Beobachten)
    
          POP                               //Breichslaenge-1 zurück in Akku1
          +     1
          T     #tmp_Bereichslaenge         //Anzahl der Bits
    
    //Pointer-Register (ARx) für Kopierschleife initialisieren
          LAR1  #tmp_Anfangsadresse         //Pointer auf Quell-Bereichsbeginn
    //      LAR2  P##tmp_E                    //TEMP-Array: Pointer auf Ziel-Bereichsbeginn
          TAR2                              //STAT-Array: eventuellen MultiinstanzOffset in Akku1
          LAR2  P##stat_E                   //STAT-Array: Pointer auf Ziel-Bereichsbeginn Grund-I.
          +AR2                              //STAT-Array: ="= + eventuellen MultiinstanzOffset
    
    //Kopierschleife
    loop: U      [AR1,P#0.0]                //E[AR1] lesen
          =      [AR2,P#0.0]                //in DIX[AR2] übertragen (bzw. L[AR2])
    
          +AR1  P#0.1                       //Quell-Pointer auf nächstes Bit
          TAR1  
          L     #tmp_Endadresse             //Quell-Endadresse
          >D                                //überschritten?
          SPB   end
          +AR2  P#0.1                       //Ziel-Pointer auf nächstes Bit
          SPA   loop                        //Schleife wiederholen
    
    //AR2 wiederherstellen
    end:  LAR2  #tmp_AR2save                //AR2 wiederherstellen
    
    //Beispiel Verarbeitung der kopierten Bits
          U     #stat_E[0]
          U     #stat_E[13]
          =     #tmp_Bit
    Die mit //** auskommentierten Zeilen sind beim Beobachten/Testen des Bausteins recht nützlich, für die Funktion aber nicht erforderlich.

    Da die Eingangsbits immer in das Array kopiert werden, ist es auch möglich, das Array in den TEMP-Bereich (Lokaldaten) zu legen. Dann darf das AR2 aber nicht zum Ziel-Pointer addiert werden.

    So wird der FB aufgerufen:
    Code:
          CALL  FB    11 , DB11
           Anfangsadresse:=E4.0
           Endadresse    :=E5.5
    Das geht auch mit symbolischen E-Adressen an den IN-Parametern.
    Weil die IN-Parameter vom Typ POINTER sind, könnte man auch P#E4.0 und P#E5.5 dranschreiben - das wird dann aber nicht symbolisch.
    Wenn man bequem E4.0 und E5.5 dranschreibt, dann wandelt Step7 das unsichtbar in P#E4.0 und P#E5.5 um.

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  11. Folgender Benutzer sagt Danke zu PN/DP für den nützlichen Beitrag:

    Limette (22.03.2011)

  12. #30
    Limette ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    25.10.2010
    Beiträge
    239
    Danke
    107
    Erhielt 2 Danke für 2 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Vielen vielen Dank.


    Wenn ich mit einer S7-300 arbeite kann ich diesen Teil rausnehmen, oder ?

    Code:
    cead: PUSH                              //( für S7-400 und PLCSIM: Akku2 = Akku1 = Bereichslaenge-1 )  
          PUSH                              //( für S7-400 und PLCSIM: Akku3 = Akku2 = Akku1 )  
          L     #tmp_Anfangsadresse         //Akku1: A.adr | Akku2: B.laenge-1 | (Akku3: B.laenge-1)
          +D                                //( S7-400 und PLCSIM: Akku2:=Akku3! )
          T     #tmp_Endadresse
    //**      LAR1                              //(zum Beobachten)
    
          POP                               //Breichslaenge-1 zurück in Akku1
    Bei L D [AR1,P#2.0] geht er leider in Stop:
    Code:
          TAR2  #tmp_AR2save                //AR2 sichern, weil dies ein FB ist
    
    //Pointer auf Quellbereichsbeginn erstellen 
          LAR1  P##Anfangsadresse           //Adresse des IN-Parameters in der Grund-Instanz
          TAR2                              //eventueller Multiinstanz-Offset
          +AR1                              //Pointer auf IN-Parameter Quell-Bereichsbeginn
          L     D [AR1,P#2.0]               //nur Speicherbereichsadresse des übergebenen POINTER
          T     #tmp_Anfangsadresse
    Ereignis 10 von 10: Ereignis-ID 16# 2522
    Bereichslängenfehler beim Lesen
    Instanz-DB, Doppelwortzugriff, Zugriffsadresse: 2
    Angeforderter OB: Programmierfehler-OB (OB 121)
    Prioritätsklasse: 1
    interner Fehler, kommendes Ereignis
    Das ist jetzt leider wieder so eine Fehlermeldung, bei der ich nicht weiter weiß. wo kann ich den nachgucken, wo genau mein Bereich startet und wo er aufhört. bei 2.0 ist er schon mal nicht. ^^

Ähnliche Themen

  1. Prog.Hilfe Behäter Min Max Wert
    Von Marcel0815 im Forum Simatic
    Antworten: 24
    Letzter Beitrag: 04.11.2009, 20:43
  2. Fehlermeldungen per Sps-Prog archivieren
    Von Robot-Sun im Forum Programmierstrategien
    Antworten: 5
    Letzter Beitrag: 06.02.2009, 23:25
  3. Suchen Fachkräfte in Roboterprog. + SPS Prog.
    Von SPS-Projekt im Forum Suche - Biete
    Antworten: 0
    Letzter Beitrag: 17.10.2008, 14:56
  4. Bllinkmerker im F-Prog
    Von mitchih im Forum Simatic
    Antworten: 10
    Letzter Beitrag: 12.05.2008, 16:18
  5. Welches Prog für s/t-diagramm?
    Von Flo-1- im Forum Programmierstrategien
    Antworten: 10
    Letzter Beitrag: 14.12.2007, 14:09

Lesezeichen

Berechtigungen

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