www.mikrocontroller.net

Forum: Compiler & IDEs Anfängerfrage zu Vergleichsoperation


Autor: Achim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, vielleicht kann mir ja jemand auf die Sprünge helfen.
Betrifft ATTINY44 und WinAVR.
Ich versteh nicht wie ich einen Vergleich anstellen muss:
Der Disassembler übersetzt:
375:        if (ADMUX==ADMUX_THR)  
+000001E2:   B187        IN        R24,0x07       In from I/O location
Das funktioniert nicht so, wie ich will. Hingegen funktionert richtig:
375:        if (ADMUX==131)  
+000001E2:   B187        IN        R24,0x07       In from I/O location
+000001E3:   3883        CPI       R24,0x83       Compare with immediate
+000001E4:   F009        BREQ      PC+0x02        Branch if equal
+000001E5:   C057        RJMP      PC+0x0058      Relative jump
Eigentlich will ich die Einstellung in ADMUX prüfen.
Vorher habe ich definiert:
#define THR_INPUT_PIN    PINA3
#define ADMUX_THR  (uint8_t)  (1<<REFS1) | (0<<REFS0)|THR_INPUT_PIN

ADMUX=ADMUX_THR;
Warum läd WinAVR bei "if (ADMUX==ADMUX_THR)" einfach nur ADMUX in R24 
und weiter nichts?
Was mache ich falsch?

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klammerung beim Makro vielleicht?
#define ADMUX_THR ( (uint8_t)  ((1<<REFS1) | (0<<REFS0)|THR_INPUT_PIN) )

Autor: tuppes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Offenbar glaubt der Compiler, dass das Vergleichsergebnis (ADMUX == 
ADMUX_THR) von nichts abhängt, also immer false oder immer true ist. Ich 
tippe auf einen Fehler in den Makros.

Wie ist PINA3 definiert?

Hinweis: Der Cast auf (uint8_t) wirkt nur auf den vordersten 
Klammerausdruck (1 << REFS1). Der Gesamtausdruck erfährt danach noch 
eine Integer-Promotion, so weit wie nötig, um die auftretenden Werte 
darzustellen (ggfs. bis unsigned long).

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>main.c:12: warning: suggest parentheses around comparison in operand of |

Klammern sind in C nie zuviel, immer nur zuwenig.

== hat eine höhere Precedence als | , und damit macht die Zeile
if (ADMUX== (uint8_t)  (1<<REFS1) | (0<<REFS0)|THR_INPUT_PIN)) 

etwas ganz anderes, als du eigentlich beabsichtigst. Der Klammerausdruck 
ist immer wahr (warum das so ist, kannst du ja selber mal rausknobeln), 
und dann schlägt der Optimierer zu, und optimiert den Vergleich weg. 
ADMUX wird aber trotzdem gelesen, da volatile.

Mit
#define ADMUX_THR  ((uint8_t)  ((1<<REFS1) | (0<<REFS0)|THR_INPUT_PIN))

funktioniert dein Programm so, wie du erwartest.

Oliver

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achim schrieb:

> Was mache ich falsch?

Spiel doch einfach mal Präprozessor und mach die Textersetzung genau so, 
wie sie auch der Präprozessor vornimmt.

Du hast

   if (ADMUX==ADMUX_THR)

und jetzt ersetzt du den Text ADMUX_THR durch

(uint8_t)  (1<<REFS1) | (0<<REFS0)|THR_INPUT_PIN

Dann kriegst du

   if( ADMUX==(uint8_t)  (1<<REFS1) | (0<<REFS0)|THR_INPUT_PIN )

und jetzt gliederst du das mal nach den C-Regelen

   if( ADMUX == (uint8_t)  (1<<REFS1) |
       (0<<REFS0) |
       THR_INPUT_PIN )

Deine Abfrage besteht also aus 3 Teilausdrücken:
   ob ADMUX gleich 1 << REFS1 ist
   Dem Wert von 0 << REFS0
   und dem Wert von THR_INPUT_PIN

Alle 3 Teilbedingungen werden mit einem binären Oder miteinander 
verknüpft und das Gesamtergebnis entscheidet dann ob der then Zweig 
genommen wird.

Autor: Achim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tausend Dank für eure schnelle Hilfe! Es klappt!
Ich habe wirklich auch die Warnung übersehen (schäm...)...

Danke auch Karl heinz für den Tip fürs Weiterstudieren!

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.