Step 7 Byte ( 8 Funktionen durch eigenes BIT gesetzt) nach BCD

PN/DP

User des Jahres 2011-2013; 2015-2017; 2020-2021
Beiträge
19.527
Punkte Reaktionen
5.882
Gibt es da etwas fertiges für, oder muss ich mir etwas "basteln" ?
Für dieses häufige Problem gibt es natürlich schon etwas fertiges: FC96 ENCO aus der Standard Library "TI-S7 Converting Blocks"
(Achtung: die Bausteinhilfe im Simatic Manager ist falsch und irreführend, die ist teilweise mit der Hilfe des FC97 DECO vermixt)

und das ganze in FUP :D
In FUP ist das Problem nur ziemlich uneffizient lösbar. Ich würde eine Function in AWL oder SCL programmieren, mit dem Algorithmus von Thomas_v2.1 in #9.
Wenn es aber unbedingt in FUP sein muß, dann läßt sich der Decoder in der Art von SPS-Totalizer #10 am leichtesten und verständlichsten in FUP realisieren.

Harald
 

Thomas_v2.1

Well-known member
Beiträge
8.839
Punkte Reaktionen
2.706
Zuviel Werbung?
->Hier kostenlos registrieren
Und das Ergebnis soll ja nur ein ein einziges Byte transferiert werden, T DB1.DBB1 oder wie es im Ursprungspost geschrieben wurde. Die Lösung funktioniert aber auch nur für genau die im 1. Post angegebenen Bitmuster. Für die Praxis untauglich.
 

PN/DP

User des Jahres 2011-2013; 2015-2017; 2020-2021
Beiträge
19.527
Punkte Reaktionen
5.882
Ist das dein ernst?
Eine Bitleiste in eine Real-Zahl wandeln und dann ohne Rücktransformation einen BCD-Wert
ausgeben.
Magst du das kurz erklären?

Dieser Trick ist auch bei Siemens bekannt, hier ein FAQ von 1999:
Maskieren vom niederwertigsten oder höchstwertigen gesetzten Bit in WORD und DWORD Variablen
Die Bits 30 bis 23 enthalten den Exponent+127.
Um die Position des ersten gesetzten Bits zu ermitteln, müssen Sie die Bits mit dem Exponenten um 23 nach rechts verschieben. Subtrahieren Sie davon 127, so erhalten Sie in AKKU1-LL die gesuchte Position.
 

Heinileini

Well-known member
Beiträge
5.676
Punkte Reaktionen
1.290
Zuviel Werbung?
->Hier kostenlos registrieren
@Hucky
PN/DP schrieb:
Die Bits 30 bis 23 enthalten den Exponent+127.
Um die Position des ersten gesetzten Bits zu ermitteln, müssen Sie die Bits mit dem Exponenten um 23 nach rechts verschieben. Subtrahieren Sie davon 127, so erhalten Sie in AKKU1-LL die gesuchte Position.
Mit "Position des ersten gesetzten Bits" ist die Position des höchstwertigen 1-Bits gemeint.
Der Siemens-Satz "Sutrahieren Sie davon 127, so erhalten Sie in AKKU1-LL die gesuchte Position" ist korrekt bei Anwendung der üblichen Durchnumerierung der Bits von rechts nach links (also beginnend beim niederwertigsten Bit) von 0 .. 31.
Für Deine Zählung von 1 .. 32 passt die Aussage nicht.

Thomas_v2.1 schrieb deshalb:
Code:
L   MB 10
DTR
SLD 1    // VorzeichenBit eliminieren! Sehr gut!!
SRD 24
L   126    // "normalerweise" 127 subtrahieren, weil "normalerweise" die BitPositionen 0 .. 31 heissen, aber hier 1 .. 32
-I
T   #FuncBCD
Mit SLD 1 und anschliessendem SRD 24 wird zunächst das "VorzeichenBit" (Bit 31) gelöscht. Das Löschen des VorzeichenBits ist korrekt und erforderlich und die ursprünglichen BitPositionen 23 .. 30 landen genauso auf den BitPositionen 0 .. 7, wie durch das o.g. "um 23 BitPositionen nach rechts verschieben".
Thomas subtrahiert dann 126 statt 127, um nicht den Exponenten selbst, sondern den (Exponenten + 1) zu erhalten, weil er den Code schon an Deine ZählWeise der Bits angepasst hat - von rechts nach links - beginnend mit 1 bis 32 durchnumeriert.
Üblich ist jedoch die Numerierung von 0 .. 31, wie bereits gesagt. Üblich, weil dies gleichzeitig der Exponent zur Basis 2 ist, der die Wertigkeit der BitPosition angibt.

Der Befehl DTR (DINT in REAL wandeln) tut fast genau das, wonach hier gefragt ist: er ermittelt die BitPosition des höchstwertigen 1-Bits in der DINT-Zahl und wir suchen nach der BitPosition des niederwertigsten 1-Bits. Das höchst- und das niederwertigste 1-Bit sind aber in unserem AnwendungsFall identisch, weil nur genau ein einziges Bit in der DINT-Variablen den Zustand 1 haben soll/darf.

Zum Experimentieren hier noch ein Link, den Harald bereits öfters hier im Forum geliefert hat.

Ausgerechnet der. Das ist doch genau DER Befehl, der uns die ganze Arbeit abnimmt!!!

möchte ich im DB12.DBB1 im BCD-Format darstellen.
:unsure: BCD?

hab gedacht, dass es evtl. einen fertigen Baustein für gibt...
Wie viel fertiger müssen denn die Lösungen noch sein, die Du hier im Forum erwartest? :unsure:
Jetzt machst Du mich aber fix und fertig! ;)
Na ja, Du könntest Dir noch den Fall ansehen, wenn im DINT kein einziges Bit den Zustand 1 hat ...
 
Zuletzt bearbeitet:
OP
H

Hucky

Well-known member
Beiträge
187
Punkte Reaktionen
1
Warum "Funktionsbaustein" (FB) ? Die Funktion muß sich nichts merken, es ist ein typischer Anwendungsfall für eine FUNCTION (FC) mit genau einem Rückgabewert.

Harald
weil ich es einfach mal so ausprobieren wollte, ich mit FBs kaum Erfahrung habe und im Programm evtl. später noch an anderer Stelle brauche.
 
OP
H

Hucky

Well-known member
Beiträge
187
Punkte Reaktionen
1
Zeig doch mal einen Screenshot.
ich hab mal den ersten Teil abgelichtet.
MB10 einlesen,
da es bei FUP keine BIT-Schiebebefehle für ein Byte gibt wird aus MB10 ein Word (#Wert0) von dem ich mit SHL-W und SHR-W die einzelnen BITs isoliere und den jeweiligen Zahlenwert ins Ausgangsword schreibe wenn das entsprechende BIT 1 ist.
Zum Schluß mach ich aus dem Ausgangswort ein Byte welches den Wert rausgibt.
Ich werde es noch bisl bei den temporären Variablen optimieren.
Cracks werden sich wahrscheinlich drüber kaputt lachen, unterm Strich zählt dass es funktioniert 😌
Ich bin halt nur Gelegenheits-"Programmierer" und viel Einfluß auf S5/S7 kommt bei mir von anderen Systemen wie 6502/6510 und Atmel.
Aktuell programmer ich eine alte Maschine passend für uns um.
Quasi komplett neu, da S7 Wäge Karten fehlten, eine 4,5K kostet und wir nicht alle Funktionen benötigen.
Es sitzt eine 315er und ein Op17 drin.
Hab noch nie vorher was mit Protool gemacht. Es ist schon spannend, man lernt sehr viel, auch wenn der Mist 25 Jahre alt ist. Ich mag den alten Kram :)
Es handelt sich um eine einfache Maschine mit Fördertechnik und zwei Abfüllpositionen.

Lange Rede, kurzer Sinn
Die Byte-BCD Funktion benötige ich um Betriebsarten (M10.0 M10.1 usw...)
am Panel (DB12.DBB1) anzeigen zu lassen
 

Anhänge

  • IMG_20221124_162528939.jpg
    IMG_20221124_162528939.jpg
    3,2 MB · Aufrufe: 18
  • IMG_20221124_162542107.jpg
    IMG_20221124_162542107.jpg
    1,3 MB · Aufrufe: 18
  • IMG_20221124_162605434.jpg
    IMG_20221124_162605434.jpg
    2,8 MB · Aufrufe: 18

PN/DP

User des Jahres 2011-2013; 2015-2017; 2020-2021
Beiträge
19.527
Punkte Reaktionen
5.882
Warum "Funktionsbaustein" (FB) ? Die Funktion muß sich nichts merken, es ist ein typischer Anwendungsfall für eine FUNCTION (FC) mit genau einem Rückgabewert.
weil ich es einfach mal so ausprobieren wollte, ich mit FBs kaum Erfahrung habe und im Programm evtl. später noch an anderer Stelle brauche.
Wenn der FC nur auf Baustein-interne Variablen und Übergabeparameter zugreift (also nicht globale Variablen, Timer, Zähler), dann kann man den FC im Programm an mehreren verschiedenen Stellen aufrufen, so oft wie man will. Und wenn der Baustein (wie bei Dir) nur aus Eingangswerten einen Ausgangswert berechnet, dann ist das eine typische FUNCTION, die man überall aufrufen kann wo man sie braucht und so oft wie man will.

Harald
 
OP
H

Hucky

Well-known member
Beiträge
187
Punkte Reaktionen
1
Wenn der FC nur auf Baustein-interne Variablen und Übergabeparameter zugreift (also nicht globale Variablen, Timer, Zähler), dann kann man den FC im Programm an mehreren verschiedenen Stellen aufrufen, so oft wie man will. Und wenn der Baustein (wie bei Dir) nur aus Eingangswerten einen Ausgangswert berechnet, dann ist das eine typische FUNCTION, die man überall aufrufen kann wo man sie braucht und so oft wie man will.

Harald
ah, ok :)
 

PN/DP

User des Jahres 2011-2013; 2015-2017; 2020-2021
Beiträge
19.527
Punkte Reaktionen
5.882
ich hab mal den ersten Teil abgelichtet.
MB10 einlesen,
da es bei FUP keine BIT-Schiebebefehle für ein Byte gibt wird aus MB10 ein Word (#Wert0) von dem ich mit SHL-W und SHR-W die einzelnen BITs isoliere und den jeweiligen Zahlenwert ins Ausgangsword schreibe wenn das entsprechende BIT 1 ist. (...)
Du denkst zu kompliziert.
Hier mein Vorschlag. Wenn genau ein Bit gesetzt ist, dann wird dessen Bitposition 1 .. 8 zurückgegeben. Wenn kein oder mehr als ein Bit gesetzt ist, dann wird 0 zurückgegeben.
ENCO_FUP_1.png ENCO_FUP_2.png

Harald
 

Anhänge

  • ENCO_FUP_CMP.awl.txt
    2,3 KB · Aufrufe: 3
OP
H

Hucky

Well-known member
Beiträge
187
Punkte Reaktionen
1
hast recht, es kann so einfach sein 🙈
In meinem Fall kann es ja nur 1,2,4,8,16,32,64 oder 128 sein 🙄
Danke 🙂
 
Zuletzt bearbeitet:
Oben