Datentypkonvertierung SCL

qpec_hagen

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

hab da mal eine Frage: kann ich einen INT im SCL auf die beiden entsprechenden Bytes konvertieren? Also ich hab zb einen DB1.DBW0 und den möchte ich auf auf zwei Variablen Test1 und Test2 vom Typ Byte "konvertieren", oder besser gesagt widerspiegeln.
Stehe da grad ein wenig auf dem Schlauch (was mitunter am Freitag liegen mag).

Danke schonmal
 
Hallo,
du machst dir eine AT-Sicht auf deine Variable, die den INT dann als 2 Bytes sieht. Also z.B. so :
Code:
myVar : INT ;
atmyVar at myVar : Array [1..2] of Byte ;

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke erstmal.
Aber kann ich das denn auch so im Code dann anwenden? Habe nämlich in meinem DB1 10 INT Variablen, welche ich per Code dann auf 20 Out Varibalen des Bausteins schreiben möchte. Und einfach durchreichen ist leider nicht möglich, da ich sie zwingend als Byte vorliegen haben muss.
 
Also sollte dann vom Prinzip so sein:
Byte1:= ??? DB1.DBW0 ; <-- erstes Byte von dem INT
Byte2:= ??? DB1.DBW0 ; <-- zweites Byte von dem INT
 
Hallo,
das, was du da als Code-Schnipsel siehst, ist ein Teil der Deklaration der Variablen. Das heißt, dass du mittels AT eine (oder mehrere) komplett andere Sichtweisen und damit ggf. auch Interpretationen von einer (oder mehreren) Variablen anlegen kannst. Da du aber eben nicht mit einer neuen Variablen arbeitest ändert das, was du in der einen Sicht machst automatisch (oder dein weiteres Zutun) den Inhalt der anderen Sicht.

Sicherlich könnte ich dir ein etwas konkreteres Beispiel liefern - leider habe ich jedoch dein Vorhaben nicht so Recht verstanden ...
Aber vielleicht kommst du mit meiner Erklärung (und etwas ausprobieren) auch schon weiter ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja das das in der Deklaration ist hab ich auch gesehen ;-)
Aber ich kann ja nicht in der Deklaration auf eine Variable in meinem DB schauen. Also so:

test AT DB1.DBW0 : Array [0..1] of Byte;

das nimmt er so garnicht an als Variablendeklaration.
Hab da grad keine Idee mehr wie ich vorgehen kann.
 
Das ist ja auch ncht der Sinn von AT.
Ich kann nur eine andere Sicht auf mir bekannte Variablen machen (alos die, die ich selber deklariere).

Aber dein WORD läßt sich ja auch noch anders "verschmickeln". Z.B. mit "AND 255" für das LOw-Byte und "div 256" für das High-byte ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sorry ... war eben etwas kurz dran, wollte aber trotzdem antworten ...

Code:
myLowByte := INT_to_Byte (myINT AND 255) ;
myHighByte := INT_to_Byte (myINT DIV 256) ;

habe ich jetzt aber nicht gestetst - sollte aber funktionieren ...

Gruß
Larry
 
Zum Thema: Würde es so machen wie in Larry´s 1. Vorschlag. Hab das neulich auch so gelöst. Array [] of Byte.

Zu Larry :) : Thema int_to_Byte..... gibt es da was in schriftform wo man das etwas genauer nachlesen kann? In der Siemens SCL Hilfe kommt ja nur folgendes :

Funktionsname Konvertierungsregel
INT_TO_BYTE WORD_TO_BYTE(INT_TO_WORD(x))


Ich meine ohne "dein" AND oder DIV kommt man jetzt da nicht wirklich weit. (Maskiert AND aus? Div teilt ??)

BTW: Was meinen Sie mit Konvertierungsregel?

Sorry für meine Unwissenheit, aber mit der SCL Hilfe alleine komm ich da jetzt nicht ganz klar.

Z.B.: myLowByte:= INT_TO_BYTE(WORD_TO_INT(%mw10)) ... was kommt jetzt da für myLowByte raus?
 
Zuletzt bearbeitet:
@Django:
Nachzulesen wüßte ich da auch nichts. Einige der Cast-Befehle von SCL bewirken auch nicht unbedingt ein AWL-Pendant - u.U. sagen sie nur dem Compiler, wie er mit dem Variablentyp verfahren soll.

Im Falle des AND / DIV :
"AND 255" oder auch "AND w#16#FF" bewirkt nichts anderes, als das in der Folge nur noch der Inhalt der niederwertigen 8 Bit des WORD verwendet werden - also die des Low-Byte. Will ich dass dann aber auch in einem Byte verwenden (also dem tatsächlichen Datentyp) dann muss ich es noch casten ...

"DIV 256" entspricht dem "nach Rechts schieben um 8 Bit" des WORD-Inhaltes. Es bewirkt, dass die höherwertigen 8 Bit des Wortes in das Low-Byte rutschen.

Im Falle von INT_to_Byte bewirkt es aber wahrscheinlich auch nichts anderes als mein oben schon genanntes maskieren mit AND. In AWL wäre das ggf. "L MW10 und T MB200". Beim Programmieren habe ich mir aber angewöhnt, dass auch als Code darzustellen, was ich bewirken möchte und nicht die Interpretations-Fähigkeit des Lesenden vorauszusetzen.

Die AT-Geschichte funktioniert natürlich nicht bei Verwendung von im Grunde unbekannten Daten (also etwas, dass sich außerhalb der Deklaration des SCL-Bausteins befindet).

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi Larry,

danke für die Hilfreiche Antwort.

Das mit AND / DIV "ausmaskieren" für High und Low byte hab ich mir schon so gedacht.

Muss aber mal probieren, (hab grad kein PG zur Hand), was dann Int_To_Byte genau macht. Wie du schon schreibst, wahrscheinlich das gleiche wie AND 255, also auf das Low_Byte "zuzugreifen". Ist aber dann nicht wirklich 100% nützlich der Befehl, wenn ich immer nur das Low_Byte damit ansprechen kann.
Wie gesagt, finde die AT Lösung am besten, vorausgesetzt natürlich die Daten sind bekannt (bei mir ja :) ).

Gruß & Dank

Django
 
Die Umsetzung mit der AT-Sicht ist aber von der Funktion her nicht unbedingt identisch zu INT_TO_BYTE().

Wenn die Übersetzungsoption SetOKFlag gesetzt ist, wird bei INT_TO_BYTE() geprüft ob der Integerwert überhaupt in ein Byte hineinpasst. Ist das nicht der Fall wird das OK-Flag zurückgesetzt, und man kann dieses Bit im folgenden Programm abfragen und entsprechend darauf reagieren.
Wenn SetOKFlag nicht gesetzt ist macht INT_TO_BYTE() nur eine Ausmaskierung mit UW 16#FF.

Das ist oft auch der Grund warum Leute meinen dass vom SCL Übersetzer generierter Code total aufgebläht ist, denn wenn die Option gesetzt ist (wahrscheinlich Voreinstellung) wird das bei jeder Typkonvertierung geprüft.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das kommt darauf an.
Mit der AT-Sicht muss ich die Prozessorarchitektur (Endianess) kennen, damit ich weiß an welcher Position im Speicher das nieder- und höherwertigste Byte einer Integer-Zahl steht.
INT_TO_BYTE() maskiert per Definition die 8 niederwertigsten Bits aus. Wobei das imho in der IEC-Norm nichtmal genau so festgelegt ist, aber die Siemens SCL-Doku gibt es so an.

Wenn man vor hat Code zu schreiben der auch auf möglichst vielen anderen ST Implementierungen funktioniert, sollte man die AT-Sicht (Siemens spezifisch) oder Pointer (Codesys spezifisch) möglichst nicht verwenden.
 
Danke erstmal für die hilfreichen Tipps. Hab es zwar noch nicht ausprobiert aber das Ausmaskieren wäre wohl das schnellste.
Wie erwähnt stand ich wohl voll auf dem Schlauch. Die Lösung sieht ganz einfach aus: ich habe einen Int im DB und wollte ja das High bzw Lowbyte getrennt haben:
LowByte: DB1.DBB0;
HighByte: DB1.DBB1;

einfach byteweise nutzen die Variable :D
 
Zurück
Oben