TIA Bool_to_Dword

Zuviel Werbung?
-> Hier kostenlos registrieren
@TheLevel, danke - leerzeichen war ein Problem. Aber warum funktioniert das bei der einen VAR und bei der anderen nicht?

Anhang anzeigen 57062
Zeile 3 ist DB absolut, Variable symbolisch, Bit absolut --> Das geht generell nicht
Zeile 4+5 sind komplett absolut -->das geht, ist aber oftmals kein guter Programmierstil
Zeile 6 ist DB symbolisch, Variable symbolisch, Bit absolut -->Mit einer Leicht anderen schreibweise (zusätzliches %) wäre das der so genannte Slice Zugriff und der geht nur auf den neuen Steuerungen (1500er)
 
Da PN/DPs Variante symbolisch funktioniert würde ich persönlich das dem absoluten Zugriff vorziehen. Dann natürlich ordentlich kommentieren. Oder eben das Programm so schreiben dass man gar nicht erst auf einzelne Bits einer Variable zugreifen muss.
 
also die Variante von Harald ist zwar elegant aber was spricht denn gegen den den von Stoky erwähnten Slice-Zugriff`?
Code:
"Test_DwordBit".Test_DwordBit%X0.0 := TRUE // nulltes bit von Test_DwordBit auf TRUE setzen

klappt bei mir mit eine 1513
1635429025189.png
 
Zuviel Werbung?
-> Hier kostenlos registrieren
oh alles klar, hatte es gerade getestet und es baut tatsächlich nicht, mit einer IM151-8. Ich dachte so eine das wäre eher eine 1500er (auch vom Namen her) aber dem ist offensichtlich nicht so
2,Unzulässiger Zugriff %X2 für #myDWord.,,,15:53:20


EDIT: Habe ich verwechselt mit den ET200SP, die können das weil sie eine 1500er verbaut haben
 
Zuletzt bearbeitet:
S7-300/400/ET200S können Slice-Zugriffe nicht, und der TIA-SCL-Compiler hatte da lange auch keine Ersatz-Anweisung für.
In der Bibliothek LGF ab V5.0.0 ab TIA V15.1 gibt es die Bausteine LGF_BitSet, LGF_BitReset, LGF_BitTest
(ich weiß jetzt gerade nicht, ob die auch für S7-300/400/ET200S verwendbar ist)

Ohne die LGF muß man zurück zu den Basics und sich den Bitzugriff selber programmieren. Das geht entweder mit den Wordverknüpfungen (wie in #06 gezeigt, was sogar für mehrere Bits gleichzeitig geht) oder man muß das (D)Word irgendwohin umkopieren, wo man die Bits einzeln ansprechen kann, und ggf. danach das (D)Word wieder zurückkopieren. Das sollte man aber nicht old-S5-style mit Schmiermerkern machen, sondern soweit möglich symbolisch per AT (oder ähnlich) eines (D)WORD und einer Bitstruktur in TEMP. In AWL kann man das etwa so machen:
16 Bits zu Word zusammenfassen
Bits aus Word lesen

In TIA-SCL kann man Bit-Adressen in DB indiziert adressieren: %DB123.DX(i,j)

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
In der Bibliothek LGF ab V5.0.0 ab TIA V15.1 gibt es die Bausteine LGF_BitSet, LGF_BitReset, LGF_BitTest
(ich weiß jetzt gerade nicht, ob die auch für S7-300/400/ET200S verwendbar ist)
Direkt für S7-300/S7-400/ET200S verwendbar ist die LGF nicht. Weil aber die SCL-Quellen in der Lib vorliegen und im wesentlichen die Wordverknüpfung Grundfunktionen (wie in #06 beschrieben) verwendet wurden (und SHL() zum Schieben der Bitmaske), kann man sie leicht portieren. (Siemens hat da offensichtlich keine Lust zu.)

Im Anhang eine SCL-Quelle der "Bit logic operations" aus der Library of General Functions (LGF) V5.0.0 für S7-300/S7-400/ET200S :
LGF_BitSet
LGF_BitSetTo
LGF_BitReset
LGF_BitToggle
LGF_BitTest
LGF_BitCount

⚠️ Habe ich nicht getestet, nicht optimiert. Nur soweit Müll entfernt und angepasst, daß sie in TIA V15.1 fehlerfrei importiert/übersetzt wird.

Harald
 

Anhänge

⚠️ Habe ich nicht getestet, nicht optimiert. Nur soweit Müll entfernt und angepasst, daß sie in TIA V15.1 fehlerfrei importiert/übersetzt wird.
'N := (#bitNo MOD #MAX_NO_OF_BITS)' in den LGF-Funktionen ist doch nicht von Dir, Harald?
Andererseits, es kommt 'MOD' drin vor, könnte also doch von Dir kommen. ;)

Egal, ich protestiere einfach mal gegen dieses Feature!
Ich finde es falsch, einen Wert >31 für die Anzahl "Schiebungen" (BitPositionen) automatisch in den Bereich 0..31 zu reparieren.
Stattdessen würde ich den Wert mit 'N := MIN(IN1:=#bitNo, IN2:=32)' "umarbeiten", oder noch lieber gar nicht.
Wenn die SchiebeZahl >31 ist, darf kein einziges Bit des DWORD adressiert werden, weil damit ein Bit im "Jenseits" gemeint ist.
Ob eine SchiebeZahl >31 beabsichtigt oder ein Fehler ist, sei dahingestellt.

Folgendes hatte ich vor Deinem Beitrag schon gebastelt. Ich bitte, Überschneidungen zu entschuldigen.
Allerdings hatte ich meiner Naivität beim IN-Parameter von SHL zunächst 'IN := 1' geschrieben. Das mit der Konstante habe ich jetzt übernommen.
Code:
// SCL :

// jeweils mit
   VAR CONSTANT
      cdValue1 : DWORD := 16#00000001;
   END_VAR

// Bit abfragen : - - - - - - - - - -
    obErgebnis := (ioDword AND SHL (IN:=cdValue1, N:=iiBitNr)) <> 0 ; // iiBitNr: 0..31

// Bit setzen : - - - - - - - - - -
    ioDword := ioDword OR SHL (IN:=cdValue1, N:=iiBitNr) ; // iiBitNr: 0..31

// Bit löschen : - - - - - - - - - -
    ioDword := ioDword AND NOT SHL (IN:=cdValue1, N:=iiBitNr) ; // iiBitNr: 0..31

// Bit invertieren ("toggle") : - - - - - - - - - -
    ioDword := ioDword XOR SHL (IN:=cdValue1, N:=iiBitNr) ; // iiBitNr: 0..31

// Bit zuweisen : - - - - - - - - - -
    ioDword := SEL (G:= ibBitValueToBeCopied, IN0:= ioDword OR SHL (IN:=cdValue1, N:=iiBitNr), IN1:= ioDword AND NOT SHL (IN:=cdValue1, N:=iiBitNr)) ;
    // A C H T U N G ! ! ! Ggfs müssen die Parameter IN0 und IN1 des SEL getauscht werden!
    // Leider bin ich aus der Beschreibung der Funktion SEL und aus dem noch dürftigeren Beispiel nicht schlau geworden.

    // alternativ mit IF
    IF ibBitValueToBeCopied XOR ((ioDword AND SHL (IN:=cdValue1, N:=iiBitNr)) <> 0) THEN
        ioDword := ioDword XOR SHL (IN:=cdValue1, N:=iiBitNr) ; // iiBitNr: 0..31
    END_IF ;

    // alternativ mit IF und temp. Variable tdBitPat
    tdBitPat := SHL (IN:=cdValue1, N:=iiBitNr) ; // iiBitNr: 0..31
    IF ibBitValueToBeCopied XOR ((ioDword AND tdBitPat) <> 0) THEN
        ioDword := ioDword XOR tdBitPat ;
    END_IF ;
Hier noch mein Versuch in AWL:
Code:
// AWL:

// Bit abfragen : - - - - - - - - - -
      L    1
      SLD  BitNr // 0..31
      L    DoppelWort
      UD
      U    <>0
      =    ErgebnisBit

// Bit setzen : - - - - - - - - - -
      L    1
      SLD  BitNr // 0..31
      L    DoppelWort
      OD
      T    DoppelWort

// Bit löschen : - - - - - - - - - -
      L    1
      SLD  BitNr // 0..31
      INVD
      L    DoppelWort
      UD
      T    DoppelWort

// Bit invertieren ("toggle") : - - - - - - - - - -
      L    1
      SLD  BitNr // 0..31
      L    DoppelWort
      XOD
      T    DoppelWort

// Bit zuweisen : - - - - - - - - - -
      L    1
      SLD  BitNr // 0..31
      L    DoppelWort
      UD
      X    ==0
      X    BitSoll
      L    DoppelWort
      SPB  Skip
      XOD
      T    DoppelWort
Skip  ...
 
Zuletzt bearbeitet:
'N := (#bitNo MOD #MAX_NO_OF_BITS)' in den LGF-Funktionen ist doch nicht von Dir, Harald?
Andererseits, es kommt 'MOD' drin vor, könnte also doch von Dir kommen. ;)
Der Code ist ziemlich original "SiemensSIMATICSystemsSupport" aus der LGF. Ich habe nur das entfernt/umgeformt, was die S7-300/400 nicht können:
- Zwang zu "optimiertem Speicher"
- Datentypen USInt zu INT geändert
- 1x Slice-Zugriff var.%X0 zu (var AND 1) = 1
- 2x "+=" aufgelöst: var += #INCREMENT; zu var:= var + #INCREMENT;
- Schwachfug/Müll in den Baustein-Beschreibungen entfernt (z.B. "this function add two complex numbers, uses: COMPLEX [UDT2]" ) :ROFLMAO:
- Name und Author auf die zulässigen 8 Zeichen verkürzt

Egal, ich protestiere einfach mal gegen dieses Feature!
Ich finde es falsch, einen Wert >31 für die Anzahl "Schiebungen" (BitPositionen) automatisch in den Bereich 0..31 zu reparieren.
Stattdessen würde ich den Wert mit 'N := MIN(IN1:=#bitNo, IN2:=32)' "umarbeiten", oder noch lieber gar nicht.
Wenn die SchiebeZahl >31 ist, darf kein einziges Bit des DWORD adressiert werden, weil damit ein Bit im "Jenseits" gemeint ist.
Ob eine SchiebeZahl >31 beabsichtigt oder ein Fehler ist, sei dahingestellt.
Ich finde auch daß das ein Fehler ist, egal wie gut der Programmierer das gemeint hat. Zumal dieses eigenwillige Verhalten in den Bausteinbeschreibungen überhaupt nicht erwähnt wird. Aber hauptsache keinen Fehler melden... der Anwender der LGF ist eh' zu doof sich diese simplen Funktionen selber zu programmieren.

Harald
 
Zuletzt bearbeitet:
Zurück
Oben