Forum: Compiler & IDEs 0b00001111 geht nicht!!


von Fritz (Gast)


Lesenswert?

Hallo

habe gerade festgestellt das avr-gcc den obigen Ausdruck nicht 
verarbeiten kann!!!!

Was kann man denn da machen, so kann doch kein Mensch programmieren?

von Johannes M. (johnny-m)


Lesenswert?

Fritz wrote:
> habe gerade festgestellt das avr-gcc den obigen Ausdruck nicht
> verarbeiten kann!!!!
In welchem Zusammenhang und v.a. mit welcher Version vom AVR-GCC? Klar, 
mit '0b00001111' kann kein Compiler was anfangen!

> Was kann man denn da machen, so kann doch kein Mensch programmieren?
Unsinn. Die Binärschreibweise macht nur in wenigen Fällen wirklich Sinn 
und sie führt des öfteren dazu, dass man sich mit den Bits verzählt und 
ewig nach dem Fehler sucht. Es gibt deutlich besser lesbare 
Alternativen.

Das aktuelle Versionen vomn AVR-GCC die Binärschreibweise überhaupt 
unterstützen, ist auch nur einer Erweiterung zu verdanken. 'Normale' 
ANSI-C-Compiler unterstützen die nämlich nicht!

von Peter D. (peda)


Lesenswert?

Fritz wrote:
> habe gerade festgestellt das avr-gcc den obigen Ausdruck nicht
> verarbeiten kann!!!!

Soweit mir bekannt ist, ist es genau umgekehrt.
Nur AVR-GCC kann das 0bxxx Format lesen, alle anderen C-Compiler aber 
nicht.


> Was kann man denn da machen, so kann doch kein Mensch programmieren?

Man schreibt einfach generell keine kryptischen Hex- oder 
Binärkonstanten ins Program, weil das kein Schwein versteht, der nach 
Dir den Code lesen soll.
So kann doch kein Mensch programmieren!

Man nimmt daher nur die in den Headerfiles definierten Konstanten für 
die IO-Register bzw. definiert sich die Portpins selber, wofür man sie 
verwendet.



Peter

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Naja, in einigen Fällen kann es schon ganz gut sein und die Lesbarkeit 
verbessern, z.B. wenn bestimmte Bits ausmaskiert werden sollen.

Ich hatte mir dafür vor der "halboffiziellen" Lösung eine Headerdatei 
mit entsprechenden Konstanten gestrickt (#define B00000000 0x00 usw.).

Aber es stimmt schon: oft benötigt man das nicht, wenn man sauber 
programmiert - genau wie die Oktalzahlen, die wohl eher ein Rudiment aus 
der Urzeit von Unix darstellen :-)

Christoph

von Fritz (Gast)


Lesenswert?

Na ja, dann halt:

PORTB=0b01010101;

mein Compiler ist avr-gcc 4.1.0 (so wie man ihn mit ubuntu bekommt)

>Es gibt deutlich besser lesbare Alternativen.<

Und die wären? Doch nicht hexadezimal. Oder etwa:

(1 << 0) | (1 << 2) | (1 << 4) | (1 << 6) usw.

Also ich persönlich halte obige Binärschreibweise für deutlich besser 
als das.

Oder wisst ihr noch andere Schreibweisen?

von Johannes M. (johnny-m)


Lesenswert?

Fritz wrote:
> Na ja, dann halt:
>
> PORTB=0b01010101;
>
> mein Compiler ist avr-gcc 4.1.0 (so wie man ihn mit ubuntu bekommt)
Der müsste es können, wenn der Rest stimmt. Und Du hast noch nicht 
erzählt, woher Du weißt, dass es nicht klappt (Fehlermeldung?).

>>Es gibt deutlich besser lesbare Alternativen.<
>
> Und die wären? Doch nicht hexadezimal.
z.B.

Als Programmierer sollte man in Nullkommanix im Kopf aus ner Hex-Zahl 
eine Bitmaske machen können...

> Oder etwa:
>
> (1 << 0) | (1 << 2) | (1 << 4) | (1 << 6) usw.
Das wäre die Standard-Schreibweise, die ich aber hauptsächlich für Bits 
verwenden würde, die klingende Namen haben (also Bits in 
Steuerregistern). Bei Ports tendiere ich zu Hexadezimal.

Aber das war ja auch nicht das ursprüngliche Thema. Fest steht, dass 
aktuelle Versionen vom AVR-GCC die Schreibweise akzeptieren. Wenn es bei 
Dir nicht klappt, wird das seine Gründe haben.

von Peter D. (peda)


Lesenswert?

Fritz wrote:
> PORTB=0b01010101;

> Also ich persönlich halte obige Binärschreibweise für deutlich besser
> als das.

Ich nicht, sie sagt nämlich überhaupt nichts aus, was damit passiert.

Ich schreib z.B.
1
PORTB = 1<<LED0_RT | 1<<MOTOR1_UP | 1<<RELAIS3;

Und dann weiß ich sofort, was dann passiert.

Bzw. ich klemme die Pins gernemal um, dann muß ich nur einmal die 
Defines ändern und nicht überall im Code irgendwelche nichtssagenden 
Binärwerte.


Peter

von Fritz (Gast)


Lesenswert?

@peter

Moment: angenommen ich habe eine Galerie von LED's an meinem PORT hängen 
und will sie in einem bestimmten Muster zb:

   _ _ _ _ _ _ 
 |X| |X| |X| |X| |
  - - - - - - - -

leuchten lassen. Was gäb es da besseres als:

PORTB=0b10101010;

zu schreiben?

von Peter D. (peda)


Lesenswert?

Fritz wrote:

> leuchten lassen. Was gäb es da besseres als:
>
> PORTB=0b10101010;

Wenn die LEDs aber auch genau so angeordnet sind.

Ich klemme immer alles wild durcheinander an die Portpins, eben wie es 
vom Layout her am besten paßt.

Daher kann (muß) ich sie mit Defines wieder richtig zuordnen.


Peter

von Johannes M. (johnny-m)


Lesenswert?

Fritz wrote:
> Moment: angenommen ich habe eine Galerie von LED's an meinem PORT hängen
> und will sie in einem bestimmten Muster zb:
>    _ _ _ _ _  _
>  |X| |X| |X| |X| |
>   - - - - - - - -
> leuchten lassen. Was gäb es da besseres als:
> PORTB=0b10101010;
> zu schreiben?
Das wäre einer der (wenigen) Fälle, in denen ich mich auch mit der 
Sinnhaftigkeit der Binärschreibweise anfreunden könnte. Aber wie gesagt: 
Immer nachzählen, ob die Anzahl der Bits auch stimmt. Sonst kann alles 
Mögliche passieren und man sucht sich nen Wolf nach dem Fehler!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Fritz wrote:

> mein Compiler ist avr-gcc 4.1.0 (so wie man ihn mit ubuntu bekommt)

Ubuntu liefert leider einen ziemlich ungepatchten (sprich: weitgehend
ungepflegten) AVR-GCC mit aus.  Der Patch für binäre Konstanten mit
0b wird erst in GCC 4.3.0 offiziell drin sein (dann natürlich nicht
nur für AVR, sondern für alles).

Wenn du eine besser gepflegte Version haben willst, kannst du dir
Bingo600's Linux-Buildscript angucken:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=42631

von Johannes M. (johnny-m)


Lesenswert?

@Jörg:
Aha. Da stecke ich als nicht-Linuxer natürlich nicht so drin...

von AVRFan (Gast)


Lesenswert?

>leuchten lassen. Was gäb es da besseres als:
>
>PORTB=0b10101010;
>
>zu schreiben?
1
PORTB = (1<<PB7) | (0<<PB6) | (1<<PB5) | (0<<PB4) | (1<<PB3) | (0<<PB2) | (1<<PB1) | (0<<PB0)

Noch zwei Beispiele in Assembler gefällig: Den Sleep Mode enable ich 
durch
1
ldi   t, 0 | 0 | 1<<SE | 0<<SM | 0 | 0 | 0<<ISC01 | 0<<ISC00
2
out   MCUCR, t

und um den Watchdog zu starten schreib ich
1
ldi   t, 0 | 0 | 0 | 0<<WDTOE | 1<<WDE | 1<<WDP2 | 1<<WDP1 | 0<<WDP0
2
out   WDTCR, t

(Es sind immer genau sieben "|".  Plätze mit Nullen ohne "<<" stehen für 
nicht definierte Bits.)

Wenn man einmal gerafft hat, dass man mit dieser Schreibweise immer 
optimalen Durchblick hat, nimmt man den höheren Tippaufwand gerne in 
Kauf.  Bei Portpins kann man noch weiter gehen und Bezeichner 
definieren, die das benennen, was an den Pins angeschlossen ist: 
PIN_LED_A, PIN_KEY_UP, PIN_KEY_DOWN, PIN_POTI, PIN_SWITCH, 
PIN_DCF77SIGNAL etc. pp. Siehe Peters Beitrag oben.

von Analog (Gast)


Lesenswert?

Mach doch einfach

PORTB|=(128+0+32+16+0+0+0+0);

bzw.

PORTB|=(128+32+16);

der compiler addiert das für Dich.

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.