www.mikrocontroller.net

Forum: Compiler & IDEs Wert einer Zuweisung !


Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab mir mal gedacht, nutze die Sache, die mich beim AVR immer ärgert
(setze 1 damits 0 wird) und schon falle ich auf die Nase.

Wenn ich eine Zuweisung teste, müßte doch eine Kopie der Zuweisung
ausgewertet werden ?

Aber der Compiler liest das GIFR nochmal ein, was natürlich in die Hose
geht.

Hier mal der Code:


    if( PIND & 1<<PD2 || (GIFR &= 1<<INTF0) ){  // check hanging on SDA
low
 b2a:   82 99           sbic    0x10, 2 ; 16
 b2c:   06 c0           rjmp    .+12            ; 0xb3a
 b2e:   8a b7           in      r24, 0x3a       ; 58
 b30:   80 74           andi    r24, 0x40       ; 64
 b32:   8a bf           out     0x3a, r24       ; 58
 b34:   8a b7           in      r24, 0x3a       ; 58
 b36:   88 23           and     r24, r24
 b38:   29 f0           breq    .+10            ; 0xb44
      Timeout_sda = time;


Mit anderen Worten, man kann nicht eine Zuweisung testen, wenn das
Register nicht 100% identisch rücklesbar ist.


Peter

Autor: Stefan Kleinwort (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anderes Problem:
In diesem Beispiel verlässt Du Dich darauf, dass alle Teile in der
if-Abfrage ausgeführt werden. Ist der erste Teil (PIND & 1<<PD2) aber
true, dann wird sofort in den Ausführungsteil gesprungen (was übrigens
C-konform ist). Die Zuweisung (GIFR &= 1<<INTF0) wird also garnicht
ausgeführt, wenn (PIND & 1<<PD2) true ist!

Viele Grüße, Stefan

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@peter: So ist die Sprache C nun einmal definiert. Das Ergebnis einer
Zuweisung ist der Wert der linken Seite, d.h der Inhalt der Variablen
oder des Registers, nach der Zuweisung. Wenn die als "volatile"
deklariert ist, dann sagt das dem Compiler, dass er noch einmal lesen
muss. Jeder andere korrekte Compiler verhält sich genauso (z.B.
Microsoft, Digital Mars).

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Btw., warum man 1 setzen muss, um ein Interrupt-Flag zu löschen, steht
in der FAQ.  Hat beim näheren Hinsehen richtig Sinn.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg,

"warum man 1 setzen muss..."

ja, daß weiß ich längst, ärgere mich jedesmal darüber.

Ich wollte ja nur das Testen und Löschen in einem Abwasch erledigen.

Aber das Beispiel hat mir gezeigt, daß Mehrfachzuweisungen sehr
gefährlich sein können und deshalb besser vermieden werden sollten.

Ein hübsches Beispiel ist noch:

x = UDR = y:

Dann enthält x alles mögliche, aber bloß nicht den Wert von y.

Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan,

das ist korrekt und auch so gewollt.

Der richtige Code sieht jetzt so aus:

 if( PIND & 1<<PD2 || GIFR & 1<<INTF0 ){
   GIFR = 1<<INTF0;


Peter

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.