Forum: Compiler & IDEs Problemchen mit ADMUX = | (0101); geht das so nicht?


von Paul H. (powl)


Lesenswert?

Hi,

um den MUX des ADC-Wandlers meines ATmega48 auszuwählen wollte ich, da 
die 4 MUX-bits die Bits 0 bis 3 des ADMUX-Registers darstellen, diese 
bei der Besetzung des ADMUX-Registers einfach per Oder-Verknüpfung 
anhängen:

ADMUX = (1 << REFS1) | (1 << REFS0) | (1 << ADLAR) | (0101);

Jedoch sthen die MUX-Bits danach offensichtlich auf 0001, nicht auf 
0101. Das bestätigt sich sowohl dadurch, dass mir das der Simulator so 
anzeigt und dass in meiner Realen Schaltung am ADC1 (MUX: 0001) und 
nicht am ADC5 (MUX: 0101) gemessen wird.

Habe ich da was nicht beachtet?

lg PoWl

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

0101 ist 65

von Peter (Gast)


Lesenswert?

Johann L. schrieb:
> 0101 ist 65

nein ist ist 101 - steht ja nichts von Binary oder Hex da.

von Mike R. (thesealion)


Lesenswert?

oder um es anders zu sagen, dein (0101) ist keine binär Zahl

von Mark .. (mork)


Lesenswert?

0101 bedeutet, dass die Ziffern "101" als eine Oktalzahl, also 1*8^2 + 
0*8^1 + 1*8^0 = 65 dezimal bzw 1000001 binär. Schreib das deshalb als 
0x5 hin, das ist binär 101.

AFAIK akzeptieren einige Versionen des avr-gcc auch die 
Binärschreibweise 0b....., was aber nicht zum offiziellen C-Standard 
gehört.

MfG Mark

von Karl H. (kbuchegg)


Lesenswert?

Paul Hamacher schrieb:

> anzeigt und dass in meiner Realen Schaltung am ADC1 (MUX: 0001) und
> nicht am ADC5 (MUX: 0101) gemessen wird.

Darf ich was fragen.

Die Bits bei der MUX Auswahl sind so gewählt, dass ihre Binärdarstellung 
genau der Nummer des Kanals entspricht.

Wenn du also

  ADMUX = (1 << REFS1) | (1 << REFS0) | (1 << ADLAR) | 5;

schreiben würdest, oder vielleicht so das ganze ein wenig mehr 
hervorhebst
1
#define ADC_CHANNEL    5
2
3
...
4
5
  ADMUX = (1 << REFS1) | (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL;

dann passiert genau das was du erwartest: Es wird am ADC5 gemessen.

Zu einfach?

von Paul H. (powl)


Lesenswert?

Okay ich ergebe mich.
Ihr habt natürlich recht, ich hab vergessen die Binärschreibweise 
anzudeuten:

0b0101 müsste es lauten, dann klappts :)

Danke für die Hilfe!
Grüße, PoWl

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Paul Hamacher schrieb:
> 0b0101 müsste es lauten, dann klappts :)

Aber auch nur, wenn der Compiler eine entsprechende 
nichtstandardkonforme Frickelerweiterung enthält. Der C-Standard kennt 
keine Binärnotation.

von Paul H. (powl)


Lesenswert?

stimmt, aber avr-studio in kombination mit winavr beherrscht das :) 
wieso ist diese schreibweise eigentlich kein c-standard? Ich fände das 
sinnvoll.

von Karl H. (kbuchegg)


Lesenswert?

Paul Hamacher schrieb:
> stimmt, aber avr-studio in kombination mit winavr beherrscht das :)
> wieso ist diese schreibweise eigentlich kein c-standard? Ich fände das
> sinnvoll.

Tja. Das tun viele - in der µC-Szene

Und genau das ist der springende Punkt. Wir, die µC-Szene, sind viel zu 
klein, als das wir da groß die Sprachentwicklung beeinflussen könnten. 
Millionen von C-Programmierern kommen gut ohne Binärschreibweise 
zurecht. Ganz einfach deswegen, weil sie sie ihr Lebtag lang nicht 
brauchen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:
> Paul Hamacher schrieb:
>> stimmt, aber avr-studio in kombination mit winavr beherrscht das :)
>> wieso ist diese schreibweise eigentlich kein c-standard? Ich fände das
>> sinnvoll.
>
> Tja. Das tun viele - in der µC-Szene
>
> Und genau das ist der springende Punkt. Wir, die µC-Szene, sind viel zu
> klein, als das wir da groß die Sprachentwicklung beeinflussen könnten.

gcc implementiert inzwischen immerhin Fixedpoint-Arithmetik à la [1] 
[2].

Das ist freilich nicht in avr-gcc aktiviert (es bedarf dazu 2 oder 3 
Zeilen, mehr nicht). In [2] und ebenfalls in gcc implementiert sind 
Named Address Spaces, womit sich Dinge wie __flash bzw. __pgm oder 
__eeprom implementieren lassen, wodurch pgmspace.h überflüssig wird: gcc 
kann damit unterschiedliche Pointer-Typed handhaben; auch 24-Bit-Pointer 
sollten damit einfach realisierbar sein. Ein "proof of concept" für 
__pgm ist exemplarisch in [3] ausgeführt. (Anwendung in pgm.c)

Was Binärkonstanten angeht, so könnte das allen innerhalb eines Headers 
geschehen, der zB ein Makro BIN() implementiert. Das ist zwar nicht ganz 
so hübsch wie 0b, aber es ist Standard-C und es ist nicht notwendig, 
dafür gcc aufzubohren.

[1] http://gcc.gnu.org/onlinedocs/gcc/Fixed_002dPoint.html
[2] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf
[3] 
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=762996#762996

von Michael G. (let)


Lesenswert?

Die Aufnahme von Binärkonstanten in den ISO-C Standard wird
schon seit Jahren angestrebt. Anfangs wurde eine Diskussion im
Komitee aus Zeitgründen verschoben (keine Priorität) und zuletzt
wurde es abgelehnt da keiner der Referenzcompiler (GCC gehört
mittlerweile dazu, nicht zuletzt dank IBM) das implementiert
hatte. Das Komitee wollte nicht nochmal Erweiterungen aufnehmen
die nicht im Feld erprobt sind. Jetzt kann zumindest der GCC mit
Binärkonstanten umgehen und je nach Akzeptanz dieser Erweiterung
wird das Feature dann irgendwann im Standard aufgenommen oder
eben nicht.

Da die Embedded Szene immer wichtiger wird (z.Zt. deutlich
größeres Wachstum als der Server/PC Bereich) stehen die Chancen
jetzt mit und durch den GCC gar nicht mal so schlecht.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Den Bedarf für Binärkonstanten kann ich auch im Embeddedbereich nicht 
wirklich erkennen.
Die Verwendung hexadezimaler Notation an deren Stelle ist keine 
Raketenwissenschaft, und wenn es auf einzelne Bits ankommt, ist 
lesetechnisch

   0b0011000000000000000001000000000

sicherlich ganz erheblich fehlerträchtiger zu lesen als

   0x18000200

Wenn es auf relevante Bits in einem Register ankommt, dann werden 
sowieso symbolische Konstanten verwendet; bei den AVR-Bitschiebern sind 
das dann sogar die Nummern der Bits (und nicht deren Werte).

Auch meine allerersten Schritte in handgedengeltem Assembler (auf 6502 
und 6809 sowie einem Z80-artigen Prozessor im Sharp PC-1500) haben mich 
eine Binärnotation nie vermissen lassen.

> ADMUX = (1 << REFS1) | (1 << REFS0) | (1 << ADLAR) | (0101);

Um auf das Beispiel des Threadstarters zurückzukommen:

Hier wäre es deutlich sinnvoller, symbolische Konstanten für die 
"Mux-Bits" 0..3 zu definieren und die zu verwenden. Ansonsten muss man, 
wenn man der Codezeile begegnet, ins Datenblatt schauen um 
herauszufinden, welche Bedeutung diese Bits 0..3 haben und warum deren 
Wert als numerische Konstante geschrieben wird.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.