Phänomen bei bitweisem UND

herdi

Level-1
Beiträge
50
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Siemens-Gemeinde,

gerade habe Untersuchung eines seltsamen Fehlverhaltens meines Programmes folgendes entdeckt:

Code:
FUNCTION test : VOID

VAR
abc:WORD;
END_VAR


abc:=16#0001; ->abc ist nun 0x0001
abc:=NOT 16#0001; ->abc ist nun 0x0000
abc:=16#0002; ->abc ist nun 0x0002
abc:=NOT 16#0002; ->abc ist nun 0x00FD
abc:=16#0004; ->abc ist nun 0x0004
abc:=NOT 16#0004; ->abc ist nun 0x00FB
abc:=16#0008; ->abc ist nun 0x0008
abc:=NOT 16#0008; ->abc ist nun 0x00F7
abc:=16#0010; ->abc ist nun 0x0010
abc:=NOT 16#0010; ->abc ist nun 0x00EF

END_FUNCTION
2 Fragen dazu:

  1. Wieso tanzt der NOT-Operator beim Wert 1 aus der Reihe? Wieso wird abc in der 2. Zeile nicht 0x00FE?
  2. Und überhaupt: Wieso wird das HighByte des Words komplett ignoriert?
Mit welchen Überraschungen muss ich bei Siemens noch alles rechnen?

Habe gestern schon feststellen müssen dass die WORD_TO_BOOL-Konvertierung nur das LSB übernimmt und somit alle geraden WORD-Werte FALSE werden und die ungeradzahligen TRUE. Wo gibts den sowas ausser bei Siemens?

Viele Grüße

Herdi
 
Zuviel Werbung?
-> Hier kostenlos registrieren
das ist mal ein schöner SCL-bug ... schaut man sich deinen baustein mal als generiertes AWL an, sieht er so aus:

Code:
*
      SET   
      SAVE  
      =     L      2.1
      L     W#16#1
      T     #abc
      L     W#16#0
      T     #abc
      L     W#16#2
      T     #abc
      L     W#16#FD
      T     #abc
      L     W#16#4
      T     #abc
      L     W#16#FB
      T     #abc
      L     W#16#8
      T     #abc
      L     W#16#F7
      T     #abc
      L     W#16#10
      T     #abc
      L     W#16#EF
      T     #abc
      SAVE  
      BE

ich würde sagen, einfach mal falsch übersetzt :rolleyes:
 
dich würde sagen, einfach mal falsch übersetzt :rolleyes:

Ich würde sagen das ganze Problem kommt daher das bei einer Hexzahl die Nullen abgeschnitten werden.
also zb 16#0001 wird zu 16#1 -> 2#1 dadurch ist es negiert 0
bei 16#0002 wird zu 16#2 -> 2#10 dadurch negiert 2#1111 1101 -> 16#FD

godi
 
Das Problem ist einzig und allein der SCL Compiler.

Wenn deine div. Konstanten durch eine Variable ersetzt werden,
wird das NOT zum AWL Befehl INVI kompiliert.

Bei den Konstanten, wird das ganze zu einer scheinbar fehlerhaften Konstante Kompiliert,
das NOT kommt im AWL-Code so gesehen gar nicht mehr vor.

Also wenn man schreibt:

abc:= NOT def;

entspricht das den AWL Code (und den eigentlich gewünschten Ergebnis)
L def
INVI
T abc

Wenn man aber schreibt:
abc:= NOT 16#0008;

AWL:
L 16#00F7
T abc


Tja, Siemens ist halt Siemens ... :sb6:

Mfg
Manuel
 
der compiler interpretiert 16#0001 als Bit
bis 16#00FF als Byte
ab 16#0100 als Word

dies tritt nur bei Konstanten auf

mit Variablen siehts anders aus:

FUNCTION FC100 : VOID
VAR
abc:WORD;
def:WORD;
END_VAR

abc:=NOT def;
END_FUNCTION


ergibt:

SET
SAVE
= L 4.1
L #def
INVI
T #abc
SAVE
BE
 
Aber meiner Meinung nach ist das eh nicht schön ein NOT auf ein Word anzuwenden.
Da gibts ja viel schönere befehle wie XOR

Probiere das:
Code:
FUNCTION test : VOID

VAR
abc:WORD;
END_VAR


abc:=16#0001; 
abc:=16#0001 XOR 16#FFFF;
abc:=16#0002; 
abc:=16#0002 XOR 16#FFFF;
abc:=16#0004;
abc:=16#0004 XOR 16#FFFF;
abc:=16#0008;
abc:=16#0008 XOR 16#FFFF;
abc:=16#0010;
abc:=16#0010 XOR 16#FFFF;
END_FUNCTION
ergibt:
Code:
  SET   
      SAVE  
      =     L      2.1
      L     W#16#1
      T     #abc
      L     W#16#FFFE
      T     #abc
      L     W#16#2
      T     #abc
      L     W#16#FFFD
      T     #abc
      L     W#16#4
      T     #abc
      L     W#16#FFFB
      T     #abc
      L     W#16#8
      T     #abc
      L     W#16#FFF7
      T     #abc
      L     W#16#10
      T     #abc
      L     W#16#FFEF
      T     #abc
      SAVE  
      BE
godi
 
Oder ne Schulaufgabe wie erstelle ich ein einerkompliment mit der S7 in SCL? :ROFLMAO:

das ist ne schöne idee! *ROFL*

aber zum thema umrechnen, ist doch nicht schwer, also als erstes würde mir da der windowsrechner einfallen ... muß man natürlich auf wissenschaftlich schalten :rolleyes:

aber auch so, im kopf, ist es nicht schwer ... einfach stelle für stelle umdrehen

0->F
1->E
2->D
3->C
...
D->2
E->1
F->0

;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Schulaufgabe

Wo wir gerade beim Thema sind:
Da können wir doch auch gleich noch auf Q-Formate eingehen......
Zahlendarstellung in 16Bit, Q15: welche Zahl ist maximal darstellbar? ;)
 
mal was anderes: wofür eigentlich eine konstante negieren :confused:


Gewohnheit: In C sieht es halt bei mir auch so aus wenn ich z.Bsp. das 3. Bit in ner Variablen x auf 0 setzen will:

x&=~(1<<3);

Ist ja eigentlich auch nichts anderes als

x:=x and not 16#0008;

Es taucht da halt genau die gleiche Konstante auf die man vorher zum setzen des Bits genommen hat:
x|=(1<<3)

bzw.

x:=x or 16#0008


BTW: Gibts da bei Siemens keine eleganten Möglichkeiten wie RESETBIT(abc,3), SETBIT(abc,3) oder so wie in CoDeSys möglich
abc.3:=true bzw. abc.3:=false;

Gruß

Herdi

PS: Die 3 würde in C natürlich per #define angegeben und könnte die Position einer LED in einem Ausgangsport sein...
 
Wo wir gerade beim Thema sind:
Da können wir doch auch gleich noch auf Q-Formate eingehen......
Zahlendarstellung in 16Bit, Q15: welche Zahl ist maximal darstellbar? ;)

jetzt mußte ich tatsächlich erstmal googlen was du meinst ... sogenannte festkommazahlen - tja, kann die s7 so nicht, aber kann man sich ja basteln

aber um auf deine 16 bits zurück zu kommen - Q15 also ... öhm

Qm.n ... also m=15, n=0 ... m+n+1=16 bit ... soweit so richtig ... maximale zahl demnach dann 2^m - 2^-n, also 2^15 - 1 = 32767 ... kleinste zahl übrigens -2^m also -32768 ...

erinnert ein wenig an INT :rolleyes: ... hättest ruhig ein anderes format auswählen können Q14.1 oder so ... brauch man nämlich auch 16bit für ;)
 
Gewohnheit: In C sieht es halt bei mir auch so aus wenn ich z.Bsp. das 3. Bit in ner Variablen x auf 0 setzen will:

x&=~(1<<3);

Ist ja eigentlich auch nichts anderes als

x:=x and not 16#0008;

Es taucht da halt genau die gleiche Konstante auf die man vorher zum setzen des Bits genommen hat:
x|=(1<<3)

bzw.

x:=x or 16#0008


BTW: Gibts da bei Siemens keine eleganten Möglichkeiten wie RESETBIT(abc,3), SETBIT(abc,3) oder so wie in CoDeSys möglich
abc.3:=true bzw. abc.3:=false;

Gruß

Herdi

PS: Die 3 würde in C natürlich per #define angegeben und könnte die Position einer LED in einem Ausgangsport sein...

AT ist die Lösung dazu!
Code:
FUNCTION test : VOID

VAR
abc:WORD;
abc_bool AT abc: ARRAY[0..15] OF BOOL;
END_VAR

abc_bool[3]:= false;

END_FUNCTION

Aja und ein SPS Programm ist kein C Programm wo man auf Rechenleistung nicht so großen wert legen muss... (speziell bei Siemens ;) )

godi
 
Zurück
Oben