WORD aus einzelnen Bits zusammensetzen

Zuviel Werbung?
-> Hier kostenlos registrieren
... In AWL ist Kais Lösung sicher die eleganteste ...
Dazu 100% Ack ...

Leider habe ich ein paar Stunden "verschlafen" ...

@Zotos:
Ich gebe dir mit deiner Argumentation grundsätzlich recht - vor allem in dem Punkt mit dem Programmierstil. Trotz alle dem hat auch jeder der Anderen Recht. Das wollte ich mit meinem Beitrag ausdrücken.
- So nebenher ... dein Vorschlag war auch nicht schlecht ... (weihräucher ... lobhudel ...:p )
 
Ich knobel grad dran, ob man nicht auch mit der Rotieroperation das Statusbit A1 Stück für Stück in den Akku reinschieben kann. Aber das scheitert wohl daran, dass es keinen vernünftigen Weg gibt, in das A1 ohne Umstände die binären Werten zu schreiben:confused:
 
Ich möchte ganz einfach mal wissen, ob jemandem auffällt was an dem Vorschlag von Kai nicht stimmt. Ich kann in dieser Runde doch nicht der einzige sein, dem das sofort ins Auge sticht? Ich meine nicht solche "Kleinigkeiten" wie das Sichern und Wiederherstellen des AR1. Nichts gegen Kai, er kann das mit Sicherheit besser. Nur hat er hier wohl nicht genügend nachdgedacht, passiert mir auch oft. Es ist schon toll, was man alles für Fehler machen kann, um ein paar Bits in ein Wort zu schreiben.


Gruß, Onkel
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich möchte ganz einfach mal wissen, ob jemandem auffällt was an dem Vorschlag von Kai nicht stimmt. Ich kann in dieser Runde doch nicht der einzige sein, dem das sofort ins Auge sticht? Ich meine nicht solche "Kleinigkeiten" wie das Sichern und Wiederherstellen des AR1. Nichts gegen Kai, er kann das mit Sicherheit besser. Nur hat er hier wohl nicht genügend nachdgedacht, passiert mir auch oft. Es ist schon toll, was man alles für Fehler machen kann, um ein paar Bits in ein Wort zu schreiben.


Gruß, Onkel

Hallo Onkel,

jetzt frag ich aber auch mal,
was meinst du?


Bitte lass uns nicht dumm sterben!

CU

Jürgen

.
 
Zuletzt bearbeitet:
Hallo Jürgen,

..Das AR1 wird nach FC - Return wieder mit dem Inhalt vor Aufruf geladen, dass macht das BS..
Also, mein BS macht das nicht, aber darum geht es mir ja auch garnicht.

Nur soviel, es handelt sich um eine Funktion (FC). Dass die Ein- und Ausgangsparameter nicht in den Lokaldaten liegen, habt ihr mir ja hoffentlich schon mal abgekauft. Weiterhin sollten die 16 Eingänge nicht im selben Operandenbereich, und schon garnicht in geordneter Reihenfolge vorliegen müssen, sonst wäre die Funktion überflüssig. Jetzt sollte es schon etwas klarer werden?

Wer die Möglichkeit hat, sollte sich mal den Code vornehmen und sich beim simulieren wundern ;) . Vielleicht auch vor und nach dem Bausteinaufruf den Inhalt des AR1 ansehen?


Gruß, Onkel
 
Zuletzt bearbeitet:
Das AR1 wird nach FC - Return wieder mit dem Inhalt vor Aufruf geladen,
dass macht das BS.
Probleme gibts m.E. nur beim AR2 bei Multiinstanzen...
.

Aus der Siemens FAQ (mehr Infos unter Beitrags-Id 14628680)
Die Verwendung der folgenden höheren Sprachkonstrukte kann dazu führen, dass die Inhalte von DB-Register und Adressregister AR1 verändert werden:
  • vollqualifizierter DB-Zugriff (z.B. DB20.DBW10) als Aktualparameter für FC's
  • FB- und Multiinstanz-CALL
  • Strukturkomponente eines Formalparameters als Operand innerhalb eines FC's oder FB's
  • Strukturkomponente eines Formalparameters als Aktualparameter für FC oder FB
 
Zuviel Werbung?
-> Hier kostenlos registrieren
aus dem Vorschlag von Kai:

L P##in_bit_00;
Lar1 ; ...Was steht jetzt im AR1 ???

L W [ar1,p#0.0]; ...und wo greift der dann hin ???


also ich denke, da es sich um eine FC handelt, ist #in_bit_00 direkt mit dem beim Aufruf zugewiesenen Aktualparameter verknüpft.

Wenn #in_bit_00 z.B. mit E2.0 als Aktualparameter belegt wird, dann müsste mit L W [ar1,p#0.0] das EW2 geladen werden.
Wird #in_bit_00 z.B. mit E2.1 belegt, müsste es Probleme geben, da für den Ladebefehl die Bitadresse<>0 ist.

Würden Kais Befehle in einem FB ausgeführt, dann würde nach den Befehlen
L P##in_bit_00;
Lar1 ;
im Adressregister die Adresse von #in_bit_00 im Instanzdatenbereich stehen.

Soweit meine Theorie.

Hat es ausser Onkel noch jemand probiert ?
 
Ich bin gerade am Ausprobieren. So wie ich das im Augenblick sehe, müssen in der Funktion das DB-Register und das Adressregister AR1 am Anfang gesichert und am Ende wiederhergestellt werden.

Gruß Kai
 
Also bei mir geht die Lösung von Kai auch wenn ich die Eingänge durcheinander würfele. Also Bit_00 := E0.1 und Bit_01 := E0.0 geht bei mir.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo moeins,

Ich will mir einen FB bauen..
Dich hätten wir ja fast vergessen. Du hast es sicherich schon so umgesetzt wie OHGN es im fünften Beitrag beschrieben hat! In solch kleinen, überschaubaren Funktionen hat die absolute Adressierung der Lokaldaten durchaus eine Berechtigung.

@Jürgen
Schlaf gut! Auch ich hatte bei Inbetriebnahmen noch nie lange Weile.


Gruß, Onkel
 

Anhänge

  • OB1 NEU.pdf
    5,6 KB · Aufrufe: 28
  • FC100.pdf
    3 KB · Aufrufe: 32
  • DB100 NEU.pdf
    3,6 KB · Aufrufe: 26
Der Vollständigkeit halber hier noch einmal die Funktion FC100 mit der Sicherung und Wiederherstellung des DB-Registers und des Adressregisters AR1:

Code:
FUNCTION "FC_BOOL_WORD_PT" : VOID
TITLE =BOOL => WORD
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : LOKALDAT
VERSION : 1.0
 
VAR_INPUT
  IN_BIT_00 : BOOL ;    
  IN_BIT_01 : BOOL ;    
  IN_BIT_02 : BOOL ;    
  IN_BIT_03 : BOOL ;    
  IN_BIT_04 : BOOL ;    
  IN_BIT_05 : BOOL ;    
  IN_BIT_06 : BOOL ;    
  IN_BIT_07 : BOOL ;    
  IN_BIT_08 : BOOL ;    
  IN_BIT_09 : BOOL ;    
  IN_BIT_10 : BOOL ;    
  IN_BIT_11 : BOOL ;    
  IN_BIT_12 : BOOL ;    
  IN_BIT_13 : BOOL ;    
  IN_BIT_14 : BOOL ;    
  IN_BIT_15 : BOOL ;    
END_VAR
VAR_OUTPUT
  OUT_WORD : WORD ; 
END_VAR
VAR_TEMP
  TEMP_DB : WORD ;  
  TEMP_AR1 : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =DB-Register und Adressregister AR1 sichern
 
      L     DBNO; 
      T     #TEMP_DB; 
 
      TAR1  #TEMP_AR1; 
 
NETWORK
TITLE =IN_BIT_00 - IN_BIT_15 (BOOL) => OUT_WORD (WORD)
 
      L     P##IN_BIT_00; 
      LAR1  ; 
 
      L     W [AR1,P#0.0]; 
      TAW   ; 
      T     #OUT_WORD; 
 
NETWORK
TITLE =DB-Register und Adressregister AR1 wiederherstellen
 
      AUF   DB [#TEMP_DB]; 
 
      LAR1  #TEMP_AR1; 
 
END_FUNCTION

Gruß Kai
 

Anhänge

  • FC100 NEU.pdf
    4,2 KB · Aufrufe: 19
Zuviel Werbung?
-> Hier kostenlos registrieren
Wer bezahlt mich eigendlich für die Nachhilfestunden hier ?

Meine Funktion FC100 arbeitet auch ohne Sicherung und Wiederherstellung des DB-Registers und des Adressregisters AR1 richtig:

http://www.sps-forum.de/showpost.php?p=107371&postcount=30

Gruß Kai

@Kai:
Klar, dein FC funktioniert und du musst auch nicht zwingend AR1 / DBreg. retten.

Ein erfahrener Programmierer weis, dass er mit offenem AR-Registern über Bausteingrenzen hinweg eben vorsichtig
umgehen muss.

Das DB1 - Register wird eh beim nächsten vollquallifizierten Zugriff wieder beschrieben,
also drohen auch da keine Probleme.

Das einzigste Argument, dass für das Retten / Laden der Register spricht, ist ein unsynchroner Aufruf
der FC, z.B. in einem Alarm - OB.

IMHO hast du alles richtig gemacht.


Also bei mir geht die Lösung von Kai auch wenn ich die Eingänge durcheinander würfele. Also Bit_00 := E0.1 und Bit_01 := E0.0 geht bei mir.

Zotos,
das ist ganz klar, da der P## nicht die Adresse des Operanden sondern die Anfangsadresse des Parameters lädt,
das ist ja der Witz des P## - Befehls.
OK, das ist schon etwas komplex, S7 - Neulinge wie du sollten vielleicht doch erst noch mit Schmiermerkerwörtern arbeiten...



@Jürgen
Schlaf gut! Auch ich hatte bei Inbetriebnahmen noch nie lange Weile.

Gruß, Onkel

Hallo Onkel,
ja, danke auch.

Ich glaub, wenn bei dir mal Langeweile aufzukommen droht, dann mischst du hier das Jungvolk auf, was? :ROFLMAO: :ROFLMAO: :ROFLMAO:


CU

Jürgen

.
 
Ich möchte ganz einfach mal wissen, ob jemandem auffällt was an dem Vorschlag von Kai nicht stimmt. Ich kann in dieser Runde doch nicht der einzige sein, dem das sofort ins Auge sticht? Ich meine nicht solche "Kleinigkeiten" wie das Sichern und Wiederherstellen des AR1.

Nur soviel, es handelt sich um eine Funktion (FC). Dass die Ein- und Ausgangsparameter nicht in den Lokaldaten liegen, habt ihr mir ja hoffentlich schon mal abgekauft. Weiterhin sollten die 16 Eingänge nicht im selben Operandenbereich, und schon garnicht in geordneter Reihenfolge vorliegen müssen, sonst wäre die Funktion überflüssig. Jetzt sollte es schon etwas klarer werden?

Ich glaube, ich verstehe langsam, worauf Onkel Dagobert hinaus will. Zumindest habe ich folgendes Problem gefunden:

Die Funktion FC100 habe ich im OB1 einmal in der FUP-Ansicht im Netzwerk 1 und einmal in der AWL-Ansicht im Netzwerk 2 eingefügt.

Wenn man sich den OB1 nun einmal in der FUP-Ansicht und einmal in der AWL-Ansicht ansieht, kann man einen interessanten Unterschied zwischen den beiden Bausteinen sehen:

Im Netzwerk 1 werden die Eingänge zunächst in Lokaldaten kopiert und mit diesen Lokaldaten wird dann der FC100 beschaltet.

Im Netzwerk 2 wird der FC100 direkt mit den Eingängen beschaltet.

Dieses hat nun zur Folge, dass der FC100 im Netzwerk 1 richtig funktioniert, der FC100 im Netzwerk 2 aber nicht.

Gruß Kai
 

Anhänge

  • OB1 - FUP.pdf
    5 KB · Aufrufe: 25
  • OB1 - AWL.pdf
    4,5 KB · Aufrufe: 23
  • FC100 - AWL.pdf
    4,2 KB · Aufrufe: 22
  • DB100.pdf
    3,6 KB · Aufrufe: 16
Hier noch ein paar Bilder aus der Simulation mit PLCSIM:

Netzwerk 1:

FC100 - OUT_WORD = DB100.DBW2

Die Eingänge des FC100 werden richtig im DB100.DBW2 gespeichert.

Netzwerk 2:

FC100 - OUT_WORD = DB100.DBW4

Die Eingänge des FC100 werden falsch oder gar nicht im DB100.DBW4 gespeichert.

Gruß Kai
 

Anhänge

  • PLCSIM - 1.jpg
    PLCSIM - 1.jpg
    405,1 KB · Aufrufe: 33
  • PLCSIM - 2.jpg
    PLCSIM - 2.jpg
    405,7 KB · Aufrufe: 22
  • PLCSIM - 3.jpg
    PLCSIM - 3.jpg
    405,5 KB · Aufrufe: 21
  • PLCSIM - 4.jpg
    PLCSIM - 4.jpg
    405,7 KB · Aufrufe: 13
  • PLCSIM - 5.jpg
    PLCSIM - 5.jpg
    387,1 KB · Aufrufe: 12
Zuviel Werbung?
-> Hier kostenlos registrieren
OB1 - Netzwerk 1:

Der FC100 im Netzwerk 1 arbeitet richtig, weil die Eingänge zunächst in Lokaldaten ab L20.0 kopiert werden und der FC100 dann mit diesen Lokaldaten beschaltet wird. Es wird dann das LW20 als Ausgang OUT_WORD ausgegeben.

Code:
      FC100:
 
      L     P##IN_BIT_00                // Zeiger auf L20.0
      LAR1  
 
      L     W [AR1,P#0.0]               // LW20
      TAW   
      T     #OUT_WORD                   // LW20

OB1 - Netzwerk 2:

Der FC100 im Netzwerk 2 arbeitet falsch. Es wird statt den Eingängen das EW100 als Ausgang OUT_WORD ausgeben.

Code:
      FC100:
 
      L     P##IN_BIT_00                // Zeiger auf E100.0
      LAR1  
 
      L     W [AR1,P#0.0]               // EW100
      TAW   
      T     #OUT_WORD                   // EW100

Gruß Kai
 
@Kai:
Klar, dein FC funktioniert und du musst auch nicht zwingend AR1 / DBreg. retten.
In welchen Fällen das Adressregister geändert wird habe ich ja schon hier geschrieben

Ein erfahrener Programmierer weis, dass er mit offenem AR-Registern über Bausteingrenzen hinweg eben vorsichtig
umgehen muss.
Was spricht dagegen, in einem FC/FB indem ich die Adressregister usw. benutze, diese grundsätzlich zu sichern und zurück zu laden. Dann bin ich immer auf der sicheren Seite. Soviel extra code ist das ja schliesslich auch nicht und ich muss mir keine Gedanken machen, ob was schiefgehen kann :)

Das einzigste Argument, dass für das Retten / Laden der Register spricht, ist ein unsynchroner Aufruf
der FC, z.B. in einem Alarm - OB.
Wird das Programm durch einen OB unterbrochen, dann werden vom Betriebssystem automatisch die aktuellen Inhalte der Akkumulatoren und
Adressregister sowie die Nummer und die Größe der geöffneten Datenbausteine im U-Stack gesichert. Beim Rücksprung in den aufrufenden Baustein werden diese wieder zurück geladen. Wenn du in deinem OB also nur den FC aufrufst, gibt es keine Probleme :)
Weitere Infos hierzu Beitrags-ID 14845057
 
Im Netzwerk 1 werden die Eingänge zunächst in Lokaldaten kopiert und mit diesen Lokaldaten wird dann der FC100 beschaltet.

Im Netzwerk 2 wird der FC100 direkt mit den Eingängen beschaltet.

Dieses hat nun zur Folge, dass der FC100 im Netzwerk 1 richtig funktioniert, der FC100 im Netzwerk 2 aber nicht.

Gruß Kai

Da sind wir auch wieder bei einem Thema, was mich vor etlichen Wochen auch sehr verwundert hat - nämlich das Step 7 beim call-Aufruf die IN-Variablen wie IN-OUT behandelt (also quasi called-by-reference), beim FUP/KOP Aufruf jedoch "by value". Hatte damals auch mit dem support telefoniert, der mir dann nochmals bestätigt hat, das dies so volle Absicht sei ( :confused: )
Hat nun der Programmierer "sauber programmiert" und von Haus aus nicht auf IN-Variablen geschrieben, spielt das de Facto keine Rolle. Muss man jedoch was Laufendes ändern, so muss man schon genau hinschauen, was da vor sich geht.
 
Zurück
Oben