24Bit Integerwert im 2er Komplement zu Real

DominikG

Level-1
Beiträge
4
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich bin absoluter Anfänger in Sachen SPS.
Ziel ist es, einen Messwert in ein Real zu wandeln.
Der Messwert kommt wie folgt an (PED 1024):
Byte 0:
Bit 7: 0=Fehler ; 1=Messwert gültig
Bit 6..3 =Fehlercode
Bit 2..0 = Anzahl der Nachkommastellen (0=1, 1=0.1, 2=0.01,...)
Byte 1..3 (=Messwert)
24 Bit Integerwert im 2er Komplement beginnend mit höherwertigem Byte

Meine Fragen sind nun diese:
1) Um z.B. die Operation DTR (Umwandlung einer Ganzzahl) zu nutzen muss ich ja ein Byte mit Nullen oder Einsen auffüllen je nach dem, was das Vorzeichenbit sagt, wie löst man das elegant?.
2) ist das Vorgehen unten im Ansatz korrekt?

L PED 1024
[Erstes Byte durch 0en oder 1en ersetzen, je nach Vorzeichenbit]
DTR
L [Info über Nachkommastellen]
/R
T [Transferieren, wohin auch immer]

Viele Grüße und Danke im Voraus,

Dominik
 
Hallo!

1. um welche SPS handelt es sich? Aus den AWL Codeschnipseln tippe ich auf eine Siemens S7-300

Ich versuche mal mein Glück, wobei unten noch ein paar Gedanken dazu kommen:
Code:
      L PED 1024
      T #Raw    // Raw ist eine Temp-Variable vom Typ DWORD

// nun zuerst die Nachkommastellen behandeln
      L #Raw    // Rohdaten einlesen
      UD DW#16#7    // alle Bits außer untere 3 ausmaskieren (16#7 = 7 hex = 2#111)
      SPL S00
      SPA S00
      SPA S01
      SPA S02
      SPA S03
      SPA S04
      SPA S05
      SPA S06
      SPA S07
S07: L 1.0e-7
      SPA NKO
S06: L 1.0e-6
      SPA NKO
S05: L 1.0e-5
      SPA NKO
S04: L 1.0e-4
      SPA NKO
S03: L 1.0e-3
      SPA NKO
S02: L 1.0e-2
      SPA NKO
S01: L 1.0e-1
      SPA NKO
S00: L 1.0e0
NKO: T #FactDec    // #FactDec enthält einen Multiplikationsfaktor für die Dezimalstellen - Temp-Variable vom Typ REAL

// Nun Messwert verarbeiten
      L #Raw
      L L#256
      /D    // eleganter Weg um vorzeichenrichtig die unteren 8 Bits zu eliminieren
      DTR
      L #FactDec
      *R
      T [wohin auch immer]

Theoretisch könnte das Motorola-Format noch dreinpfuschen, je nachdem wie die 3 Bytes Messwert nun tatsächlich codiert sind. Es könnte also noch sein, dass du die Bytes noch vertauschen muss.


Etwas kürzer und noch schwerer nachvollziehbar wird die Sache, wenn man direkt im Exponenten der Real-Zahl herumfummelt. z.B.
Code:
      L PED 1024
      T #Raw    // Raw ist eine Temp-Variable vom Typ DWORD

// Zuerst Messwert herauslösen
      L #Raw
      L L#256
      /D    // eleganter Weg um vorzeichenrichtig die unteren 8 Bits zu eliminieren
      DTR
      L #FactDec
      *R
      T #MesswertRaw    // Temp-Variable vom Typ REAL

// nun die Nachkommastellen einarbeiten
      L #MesswertRaw
      UD DW#16#7F800000    // Exponenten herauslösen
      SRD 23
      L #Raw    // Rohdaten einlesen
      UD DW#16#7    // alle Bits außer untere 3 ausmaskieren (16#7 = 7 hex = 2#111)
      -D
      SLD 23
      L #MesswertRaw
      UD DW#16#807FFFFF    // alle anderen Bits mit Ausnahme des Exponenten holen
      OD
      T [wohin auch immer]

Wieder bleibt die Frage offen, wie die 3 Bytes Messwert genau codiert sind - eventuell muss im ersten Teil noch was gedreht werden

Die langweiligste Lösung setzt auf dem Zusammenhang x^y = exp(ln(x)*y) auf
Code:
      L PED 1024
      T #Raw    // Raw ist eine Temp-Variable vom Typ DWORD

// Zuerst Messwert herauslösen
      L #Raw
      L L#256
      /D    // eleganter Weg um vorzeichenrichtig die unteren 8 Bits zu eliminieren
      DTR
      L #FactDec
      *R
      T #MesswertRaw    // Temp-Variable vom Typ REAL

// nun die Nachkommastellen einarbeiten
      L #Raw    // Rohdaten einlesen
      UD DW#16#7    // alle Bits außer untere 3 ausmaskieren (16#7 = 7 hex = 2#111)
      DTR
      L 2.302585e0    // ln(10)
      *R
      EXP
      L #MesswertRaw
      *R
      T [wohin auch immer]

Bin für Korrekturen offen ;-)
 
Byte 1..3 (=Messwert)
24 Bit Integerwert im 2er Komplement beginnend mit höherwertigem Byte

Meine Fragen sind nun diese:
1) Um z.B. die Operation DTR (Umwandlung einer Ganzzahl) zu nutzen muss ich ja ein Byte mit Nullen oder Einsen auffüllen je nach dem, was das Vorzeichenbit sagt, wie löst man das elegant?.
Dein AWL-Code sieht aus als wäre Deine nicht spezifizierte SPS eine Siemens S7.
Da die S7 Big-Endian arbeitet müßte da das höchste Byte mit dem Vorzeichen aufgefüllt werden. Dazu kann man erst mit 256 multiplizieren und dann wieder durch 256 dividieren, oder man nutzt Schiebeoperationen:
Code:
L PED1024
SLD 8     //24-Bit-Integer zu Bit .31 ausrichten (höchstes Byte rausschieben)
SSD 8     //vorzeichenrichtig wieder zu Bit .0 ausrichten
DTR
...

Harald
 
Hallo,
Ja, das hatte ich vergessen. Ist eine Siemens S7.
Ich melde mich sobald ich eure Tips versucht habe umzusetzen.
Vielen Dank schonmal!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

danke euch nochmal. Mit euren Tips funktioniert das Ganze einwandfrei mit folgendem Code:

Code:
Netzwerk 1: Titel: Valid?
   U E1024.7
   =#Valid

Netzwerk 2: Titel: Errorcode
   L EW1024
   L B#16#78
   UW
   SRW 3
   T #Errorcode

Netzwerk 3: Titel: Decimals
   L EB1024
   L B#16#7
   UW
   T #Decimals
   L#Decimals
   L 0
   ==I
   SPBN dec1
   L 1.0e+000
   SPA decE
 dec1: L #Decimals
   L 1
   ==I
   SPBN dec2
   L 1.0e+001
   SPA decE
 dec2:  L #Decimals
   L 2
   ==I
   SPBN dec3
   L 1.0e+002
   decE 
   
   [...]
   
 decE:  T #Divisor

Netzwerk 4: Titel: Value DInt
   U #Valid
   SPB val1
   L L#99999999
   SPA val9
 val1: L ED1024
   SLD 8
   SSD 8
 val9: T #ValueD

Netzwerk 5: Titel: Value Real
   L #ValueD
   DTR
   L #Divisor
   /R
   L -1.00e+000
   *R
   T #ValueR
  
Netzwerk 6: Titel: Calibration Offset
   U E5.3
   FP M30.0
   U #Valid
   SPBN calE
   L #ValueR
   L #Master
   -R
   T #ValueOffset
 calE: NOP0

Netzwerk 7: Titel: Calibrated Measuring Value
   L #ValueR
   L #ValueOffset
   -R
   T #ValueCalibrated

Grüße,
Dominik
 
funktioniert das Ganze einwandfrei mit folgendem Code:

Code:
Netzwerk 2: Titel: Errorcode
   L E[COLOR="#FF0000"][U]W[/U][/COLOR]1024
   L B#16#78
   UW
   SRW 3
   T #Errorcode
Tippfehler? Bei "EW1024" liefert das Programm nicht den Errorcode sondern die 4 Bits 6..3 aus EB1025

Vorsicht! Datenkonsistenz bei mehrfachem Zugreifen auf die Eingangsadresse! Das mehrfach Zugreifen auf E1024 funktioniert nur, wenn E1024 im Prozessabbild der Eingänge liegt. Liegt E1024 außerhalb des Prozessabbildes dann wird immer wieder auf die Peripherieadresse zugegriffen und jeder Zugriff kann ein anderes Ergebnis liefern. Also: nur ein einziges mal (P)ED1024 lesen und auf eine (temporäre) Variable umspeichern und dann nur noch auf diese Variable zugreifen.

Harald
 
Zuletzt bearbeitet:
Zurück
Oben