Hallo, wie präfixt man denn in C (WinAVR) eine Binärzahl? also 0x für Hexadezimal, was nehm ich für z.B. R16 = (binär)00110001 statt R16 = 0x31 ?
1 | R16 = 0b00110001; |
Das funktioniert zwar eigentlich immer, aber ist wohl nicht ANSI-C... wurde hier mal im Forum ausdiskutiert. P.S.: Du brauchst ein gutes C-Buch oder Tutorial...
danke. Ich hab es versucht mit dem GCC-Tutorial hier und dem von Helmut Schellong, aber nichts gefunden.. Vielleicht auch übersehen.
Es ist auch eine non-standard-Erweiterung, die allerdings von allerlei Compilern im Microcontroller-Umfeld verstanden wird. Es gab sie bereits einige Jahre als Patch für den AVR-GCC, mittlerweile wurde sie vom GCC als Erweiterung akzeptiert und ist seit GCC 4.3 nun standardmäßig mit dabei.
Kann dem Jungen mal jemand ein C-Buch schenken? Wir könnten ja auch eine Spendensammelaktion machen, um so ein Buch zu finanzieren. Oder wir starten eine gemeinsame meditative Google-Such-Selbsthilfegruppe um brauchbare Tutorials zu finden. :)
> Kann dem Jungen mal jemand ein C-Buch schenken? Ich schenk ihm einen Link, da steht das auch drin: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
Detlaus wrote:
> Kann dem Jungen mal jemand ein C-Buch schenken?
Das würde nichts helfen, denn ein ordentliches C-Buch wird kaum die
GCC-Erweiterungen beschreiben.
Vielleicht ja 'ne sehr konservative Sichtweise, aber auf solche Erweiterungen sollte man sich nicht einlassen. Stattdessen sollte man lernen, mit hexadezimalen Zahlen zu arbeiten. Das ist nicht sehr schwierig, man muss sich gerade mal 16 Bitmuster einprägen. Hat man das geschafft, dann sieht man die Bitmuster, wenn denn sie einen überhaupt interessieren. Findet man das zu anstrengend und zu schwierig, sollte man sich vielleicht nach einem anderen Hobby umsehen - Briefmarken züchten oder Goldfische sammeln. Noch schlimmer als die eigene Bequemlichkeit, mal was zu lernen, ist der so erzeugte nichtportierbare Quelltext. Das ist Schrott. Und das nur, weil jemand nicht 0xA anstelle von 0b1010 schreiben kann. Meine Güte.
Man könnte sich ja auch ein Makro schreiben, jetzt mal auf die Schnelle nur für 4 bits (nicht getestet): #define BIN4(x) (((x/1000)&1)<<3)|(((x/100)&1)<<2)|(((x/10)&1)<<1)|(x&1) zahl = BIN4(1010) Der compiler sollte die Zahl dann beim compilieren ausrechnen und nicht meckern (hoffentlich) :-)
Für lernresistente ließen sich auch einfache Macros à la #define B0000 0 #define B0001 1 #define B0010 2 ... #define B1111 15 oder das ganze auch achtstellig definieren. Einfacher aber wäre es, sich auf $Körperteil zu setzen und die 16 Bitkombinationen eines 4-Bit-Nibbles auswendig zu lernen.
Rufus t. Firefly wrote: > Einfacher aber wäre es, sich auf $Körperteil zu setzen und die 16 > Bitkombinationen eines 4-Bit-Nibbles auswendig zu lernen. Auswendig lernen ist aber eigentlich Käse. Besser versuchen, zu verstehen, wie Binär-, Dezimal- und Hexadezimalsystem funktionieren. Dann kann man sich das nämlich in Nullkommanix herleiten...
Läuft schnell auf's gleiche raus. Genauso wie man mit der Zeit die Zweierpotenzen mindestens bis 2^16 auswendig kennt.
A. K. wrote: > Läuft schnell auf's gleiche raus. Genauso wie man mit der Zeit die > Zweierpotenzen mindestens bis 2^16 auswendig kennt. Ist zwar im Prinzip korrekt, aber man sollte Zahlensysteme wenigstens grundlegend verstanden haben. Und wenn man das Dezimalsystem versteht, dann versteht man auch schnell alle anderen. Leider hakt es da bei vielen...
Mit Portierbarkeit ist es wie mit premature optimization - man kann ganz toll viel Zeit darin versenken und am Ende portiert man doch nirgendwo hin. Ich habe schon Cross-Platform programmiert und auch schon portiert, aber wegen ein paar 0b.... die ein neuer Compiler vieleicht nicht versteht, wachsen mir keine grauen Haare. Das erledigt zur Not ein kleines Script in ein paar Minuten. Also ziehe ich die angenehmere Lesbarkeit fuer mich und jeden Anderen, der mal in den Code guckt, einer hypothetischen Portabilitaet allemal vor.
@Peter Stegemann: Ist richtig, die Portierbarkeit ist sowieso meist schon durch andere Dinge nicht gegeben (fängt schon bei den Bibliotheken an). Allerdings verleitet die Binärschreibweise gerade Anfänger dazu, selbst Dinge, die man gut lesbar unter Verwendung der Bitnamen schreiben könnte, in 0bxxxxxxxx zu schreiben, was eine Fehlersuche bzw. Änderung am Code zur Tortur machen kann. Imho ist die Binärschreibweise wirklich nur da sinnvoll, wo es gewünscht ist, dass man ein Bitmuster direkt sehen kann. In den meisten Fällen ist, wenn es um das Setzen von Bits geht, die (1 << XYZ)-Schreibweise sinnvoller. Die Binärschreibweise birgt auch die nicht zu unterschätzende Gefahr, dass man sich mit den Stellen verzählt und stundenlang nach dem Fehler sucht.
> > Einfacher aber wäre es, sich auf $Körperteil zu setzen und die 16 > > Bitkombinationen eines 4-Bit-Nibbles auswendig zu lernen. > Auswendig lernen ist aber eigentlich Käse. Besser versuchen, zu > verstehen, wie Binär-, Dezimal- und Hexadezimalsystem funktionieren. > Dann kann man sich das nämlich in Nullkommanix herleiten... Ich wollte die Messlatte nicht allzuhoch legen. "Verstehen" und "herleiten können", das ist doch noch viel komplizierter ... > Also ziehe ich die angenehmere Lesbarkeit ... Ab einer gewissen Anzahl Stellen ist eine binärzahl nicht mehr "angenehmer" lesbar, das steigert nur die Fehlerrate. Wer hat schon Lust, in einem Quelltext 16-Bit-Binärzahlen auf Vollständigkeit abzuzählen ? Ich sehe da keinerlei "angenehmere Lesbarkeit".
Rufus t. Firefly wrote: > Wer hat schon Lust, in einem Quelltext 16-Bit-Binärzahlen auf > Vollständigkeit abzuzählen ? Weiss grad nicht in welcher Sprache, aber irgendwo geht 0b0001_0010_0100_1000 und das ist dann doch lesbar. Aber persönlich verwende ich die (1<<x) Notation oder Hex, ja nachdem was besser passt. Zentral als Hardware-Konfiguration definiert, damit die Module nicht von der Portverteilung abhängen.
Johannes M. wrote: > Imho ist die Binärschreibweise wirklich > nur da sinnvoll, wo es gewünscht ist, dass man ein Bitmuster direkt > sehen kann. In den meisten Fällen ist, wenn es um das Setzen von Bits > geht, die (1 << XYZ)-Schreibweise sinnvoller. Bei mir z.B. bei den Farbdefinitionen fuer's Display. Fuer Registergeschichten verwende ich natuerlich die Bitdefinitionen. > Die Binärschreibweise birgt auch die nicht zu unterschätzende Gefahr, > dass man sich mit den Stellen verzählt und stundenlang nach dem Fehler > sucht. Bei der Hex-Schreibweise gibt es gar nix zu zaehlen, das ist nicht wirklich sicherer ;-)
Johannes M. wrote: > @Peter Stegemann: > Ist richtig, die Portierbarkeit ist sowieso meist schon durch andere > Dinge nicht gegeben (fängt schon bei den Bibliotheken an). AVR-Code kann man durchaus portabel halten. Komplexere AVR-Prgramme lass ich einfach für den PC übersetzen, da hat man ganz andere Analysemöglichkeiten als in einem Simulator. Einen kleinen Kompatibilitäts-Header, der Sachen wie avr/pgmspace.h etc. rausparametriesiert, und schon geht's los! Ich hatte den Code ursprünglich auch mit 0b*** gespickt, aber ein Host-gcc mechert da rum. Bevor ich ewig rumsuche oder mir den Wolf scripte hab ichs also wieder rausgeschmissen und Standard geschrieben. Auf 0b*** kann man nich nichtmal ein Makro definieren (falls man cpp verwendet und sich nicht den Horror mit m4 antun will). Und bei großen Konstanten wie 0b11001101000010101000010111110011ul würd ich auch nicht sagen, daß das die Lesbarkeit fördert. Ein
1 | 0xcd0a85f3ul // 11001101 00001010 10000101 11110011 |
tut's doch auch. Johann
Johann L. wrote: > Ich hatte den Code ursprünglich auch mit 0b*** gespickt, aber ein > Host-gcc mechert da rum. Nun, du weißt doch, wie man einen GCC neu baut (also auch den für den Host) :-). > Auf 0b*** kann man nich nichtmal ein Makro definieren Ja klar, sonst wäre es ja auch nie als language extension durch gegangen.
A. K. wrote: > Weiss grad nicht in welcher Sprache, aber irgendwo geht > 0b0001_0010_0100_1000 und das ist dann doch lesbar. Das dürfte Spin sein. Da kann man in allen Zahlen solche Trennzeichen einfügen. Ich verwende die b0101010 Schreibweise auch, aber nur da wo es wirklich sinnvoll ist, nämlich bei LCD Controllern. Da werden in Datenblättern die Register üblicherweise alle in Binär angegeben, wieso also den Aufwand machen das im Kopf umzurechnen und eventuell noch einen Fehler einzubauen? Wenn das im Code genauso aussieht wie im Datenblatt, kann man auch viel besser vergleichen.
Wow, hier geht es ja heiß her.. ich kann im Kopf von hex nach binär und umgehehrt, jedenfalls in einem Byte. Aber manchmal ist binär schreiben praktisch (siehe oben) Ich will ja in einer "Hochsprache" programmieren der Übersicht halber. Selbst in Assembler kann man binär schreiben..
CAnfänger wrote: > ich kann im Kopf von hex nach binär und umgehehrt, jedenfalls in einem > Byte. Ich kannte mal einen, der konnte fliessend ASCII-Hex lesen. Irgendwie cool, irgendwie aber auch total ueberfluessig...
Johann L. wrote: > Komplexere AVR-Prgramme lass ich einfach für den PC übersetzen, da hat > man ganz andere Analysemöglichkeiten als in einem Simulator. Was schreibst du denn fuer komplexere AVR-Programme, die du "einfach" fuer den PC uebersetzen kannst? Meine komplexeren Programme brauchen die Timer, externe Hardware wie EEPROMs, Displays...
Benedikt K. wrote: >> 0b0001_0010_0100_1000 und das ist dann doch lesbar. > > Das dürfte Spin sein. Besser bekannt: Perl.
CAnfänger wrote: > Wow, hier geht es ja heiß her.. > > ich kann im Kopf von hex nach binär und umgehehrt, jedenfalls in einem > Byte. Aber manchmal ist binär schreiben praktisch (siehe oben) Ich will > ja in einer "Hochsprache" programmieren der Übersicht halber. Selbst in > Assembler kann man binär schreiben.. Nunja, C ist eben keine Sprache die von Anfängern oder für Anfänger konzipiert wurde... Jörg Wunsch wrote: > > Nun, du weißt doch, wie man einen GCC neu baut (also auch den für den > Host) :-). Ich hab noch nie einen canadian cross gebuildet, wär auch mal interessant zu sehen, wie das geht. Also ein gcc für das build-host-target Tripel linux-mingw32-mingw32 oder linux-mingw32-avr. So wie ich das sehe ist WinAVR-avr-gcc kein canadian cross, sondern ein native build unter msys/mingw32? Johann
> Ich kannte mal einen, der konnte fliessend ASCII-Hex lesen. Irgendwie > cool, irgendwie aber auch total ueberfluessig... Das koennen alle aelteren Leute. Ich konnte auch mal alle Z80 Hexcodes/Assemblerbefehle auswenig. (naja wenigstens die wichtigsten 50%) Lag aber nur daran das es damals noch keinen Assembler gab und man alles auf Papier von Hand machen musste. Ausserdem hasse ich seitdem relative Spruenge. :-) Olaf
Also ich habe schon in anderen Sprachen programmiert und "C" steht bei mir für "cryptic". Paßt vom Stil zu Deinem Sprachdurcheinander im letzten Absatz. "Ich hab noch nie einen canadian cross gebuildet" lach dann schreib lieber alles auf englisch and try to impress even more with it. :-) Aber jetzt seh ich mal wie verwöhnt ich z.B. von MS Visual Studio bin. AVR Studio dagegen ist echt hart. Kein Automatische Vervollständigung, immer auf Groß- und Kleinschreibung achten, keine Variablenanpassung, die Stelle wo was deklariert ist bzw. defines / .equ in externen Dateien muß man selber suchen etc. etc. Aber ich beiße mich durch! :-)
Olaf wrote: > Das koennen alle aelteren Leute. Ich konnte auch mal alle Z80 > Hexcodes/Assemblerbefehle auswenig. (naja wenigstens die wichtigsten > 50%) Der war damals vieleicht 2-3 Jahre aelter als ich und heute wahrscheinlich auch noch ;-) Und im Uebrigen war er ansonsten kaum in der Lage, eine Loesung zu produzieren - nur kleine, zwar interessante aber kaum verwendbare Spielereien.
Johann L. wrote: > Ich hab noch nie einen canadian cross gebuildet, wär auch mal > interessant zu sehen, wie das geht. Also ein gcc für das > build-host-target Tripel linux-mingw32-mingw32 oder linux-mingw32-avr. Verstehe ich nicht ganz. Wenn du als Ziel ein mingw32 haben willst, warum baust du dann den Compiler nicht gleich native dort? Ich meinte das ja auch nur, weil du mit dem GCC 4.3 ohne Patches in den ,,Genuss'' der 0b-Implementierung kommst ;-) und dann deine Quellen wieder 1:1 portierbar sind. > So wie ich das sehe ist WinAVR-avr-gcc kein canadian cross, sondern ein > native build unter msys/mingw32? Ja, das müsste dann mingw32-mingw32-avr sein, ggf. aber auch cygwin-mingw32-avr -- so genau habe ich die build triplets nie verstanden. Ich glaube, Eric baut am Ende alles unter Cygwin, damit er nicht in zwei verschiedenen Umgebungen bauen muss. Manche Dinge (wie AVaRICE oder Insight) brauchen die Posix-API-Emulation von Cygwin (auch zur Laufzeit, d. h. sie hängen von der cygwin1.dll ab). Andere Teile (binutils, GCC, AVRDUDE) werden aber so konfiguriert, dass sie trotz Bauens innerhalb Cygwin zur Laufzeit pures Win32-API benutzen, also mingw32 (und damit nicht von cygwin1.dll abhängen).
Peter Stegemann wrote: > Bei mir z.B. bei den Farbdefinitionen fuer's Display. Oder für Steuersequenzen für nen Schrittmotor oder für ein einfaches LED-Lauflicht. Aber da hört's dann auch schon auf... > Bei der Hex-Schreibweise gibt es gar nix zu zaehlen, das ist nicht > wirklich sicherer ;-) Wie gesagt, es kommt drauf an, um was für Werte es sich handelt. Bitmuster zur Ansteuerung eines Ports -> kann man durchaus in binär machen. Bits setzen in Steuerregistern -> Bitte in (1 << FIRLEFANZ)-Schreibweise. Belegen von Registern / Variablen mit Zahlenwerten -> Dezimal- oder Hexadezimalschreibweise, je nachdem, was für ein Wert es sein soll.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.