Griaß eich,
Ich sags im vorraus ich kenn mich zu diesem Thema nicht besonders aus.
Ich möchte gerne, rein nur weil es mich interessiert, einen "Befehl"
schreiben um mir unnötige Arbeit zu sparen.
Gleich ein Beispiel:
Beim ATmega gibt es den befehl "sbit" nicht, sondern man muss sich das
jeweilige Bit maskieren.
Jetzt hab ich mir gedacht man könnte ja einen Befehl schreiben der einem
diese Arbeit abnimmt.
d.h.: man schreibt im Programm sbit variable = (PORTxy, PINnr);
und der compiler erkennt das sbit variable das PORTxy ist mit einer
Maske die der PINnr entspricht das man das richtige Bit auf der Variable
hat.
Muss man dazu jetzt Assembler-Programmieren können, oder muss man das
nur in eine #include Datein einfügen...ich hab wirklich keine Ahnung.
Leider ist das sehr schlecht erklärt, aber ich weiß nicht wie ich mich
ausdrücken soll. Wenn ihr es nicht versteht ist es auch nicht schlimm
weil es wie gesagt nur eine Interesse von mir ist.
Danke
LG
Hans
Hans Gruber schrieb:> Ich möchte gerne, rein nur weil es mich interessiert, einen "Befehl"> schreiben um mir unnötige Arbeit zu sparen.
In C?
> Muss man dazu jetzt Assembler-Programmieren können, oder muss man das> nur in eine #include Datein einfügen...ich hab wirklich keine Ahnung.
Du kannst nicht einfach ein neues Schlüsselwort in den Compiler
einfügen.
Was du machen kannst: du kannst dir entsprechende Makros machen, die dir
eine alternative Schreibweise ermöglichen. Letzten Endes läuft es aber
immer darauf hinaus, das du wissen musst, wie man das in reinem C
schreiben würde.
> Leider ist das sehr schlecht erklärt,
es ist ganz einfach.
Erst mal musst du wissen, wie sich das in C #ohne# dein Makro schreiben
würde.
um Bit 4 am Port C auf 1 zu setzen würdest du schreiben
PORTC |= ( 1 << 4 );
so.
was davon ist jetzt variable und was ist konstant?
der Port Name ist offensichtlich variabel und auch die Bitnummer.
Allgemein würde man also schreiben können
port |= ( 1 << bit );
gut.
Nachdem feststeht, was in C Form rauskommen muss, überlegt man sich, wie
man es stattdessen schreiben möchte
SBIT( port, bit );
auch gut. d.h. der Text
SBIT( port, bit )
muss durch den Text
port |= ( 1 << bit )
ersetzt werden, wobei die 'unbekannten' Dinge port und bit einfach
übernommen werden können.
Also muss dein Makro so aussehen
#define SBIT( port, bit ) port |= ( 1 << bit )
schreibst du dann im C-Programm
SBIT( PORTD, 6 )
dann ersetzt der Präprozessor diesen Text anhand des #define durch
PORTD |= ( 1 << 6 )
und du hast eine dir genehme Schreibweise in deinem C-Programm
eingeführt.
Das ganze kann man jetzt natürlich auch noch wesentlich weiter treiben.
Mit Strukturen und Bitfeldern lässt sich da noch einiges machen, aber
fürs erste sei das mal so genug.
Und kauf dir ein C-Buch!
> Beim ATmega gibt es den befehl "sbit" nicht
Das ist eine Erweiterung, die ich bisher nur für 8051ger gesehen habe.
Und auch da nur für den Speicher, der einzelne Bits addressieren kann.
> der compiler erkennt das sbit variable
Dann müsstest Du den Compiler modifiziern. Schau Dir mal die Sourcen vom
AVR-GCC an, die sind öffentlich verfügbar da open source. C- Makros
reichen da nicht ohne weiteres.
Aber: Will man eigentlich auch nicht. Viel besser ist sowas:
1
#define LED_ROT_PIN 1
2
#define LED_ROT_PORT PORTA
3
#define LED_ROT_AN do { LED_ROT_PORT &= ~(1<<LED_ROT_PIN); } while (0)
4
#define LED_ROT_AUS do { LED_ROT_PORT |= (1<<LED_ROT_PIN); } while (0)
Jim Meba schrieb:> #define LED_ROT_AN do { LED_ROT_PORT &= ~(1<<LED_ROT_PIN); } while (0)> #define LED_ROT_AUS do { LED_ROT_PORT |= (1<<LED_ROT_PIN); } while (0
Was sollen die do ... while?
@ Karl Heinz Buchegger:
Vielen Danke für die rasche Antwort. UNd im Prinzip ist das eig genau
das was ich will.
Kann man dies jetzt vl noch in eine #include Datei einbauen, dass man
dieses Makro nicht immer bei jedem Programm dazuschreiben muss?
LG
Hans
Noch ein nachgeschobener Grund, warum so etwas gar nicht gehen soll:
Wenn sich jeder so seine "Sprache" zusammenbastelt, sind alle Vorteile
der Hochsprache wieder weg, da diese gerade den Vorteil leicht zu
merkender und halbwegs universeller Schlüsselworte hat.
Markus schrieb:> Jim Meba schrieb:>> #define LED_ROT_AN do { LED_ROT_PORT &= ~(1<<LED_ROT_PIN); } while (0)>> #define LED_ROT_AUS do { LED_ROT_PORT |= (1<<LED_ROT_PIN); } while (0>> Was sollen die do ... while?
Das hatten wir schon mindestens einmal.
Es bewirkt letztlich, daß die ganze Ersetzung immer als eine Anweisung
erscheint, egal ob mit oder ohne geschweifte Klammern drumrum.
-> Suchfunktion
Klaus Wachtler schrieb:> PS: Weil sonst das ## nicht funktioniert
Habs eben getestet und bekomme vom Präprozessor den gleichen Output,
egal ob ich SBIT oder SBIT_ verwende (gcc 4.6.2).
lager schrieb:> Interessant, dass in fast jedem C-Thread immer ein "Kauf Dir ein C-Buch"> auftaucht.
Weiß nicht, ob da anderes Publikum unterwegs ist.
Aber was soll es, hier jeden Tag erneut den K&R abzuschreiben, nur weil
manche nicht selber nachschlagen wollen?
Der OT hier hat 0 Ahnung von C, und mit jeder Erklärung tun sich bei ihm
neue Lücken auf.
Wieso soll er nicht erstmal selber etwas lesen?
Wenn er nicht weiß, wie man ein Makro in einer Headerdatei bekommt, hat
er halt noch nicht viel aktiv gelernt.
Ist in Ordnung, seine Sache.
Aber weisst du, wieviele Leute C lernen wollen oder müssen?
Soll man denen jede Trivialität einzeln vorkauen, nur damit sie kein
Buch aufschlagen müssen?
Bei AVR kommt übrigens (oft zu Recht) der heiße Tip, mal das
AVR-Tutorial zu lesen.
Das beantwortet 95% der Fragen zu dem Thema, und ist genau dafür da, daß
nicht jeder einzeln mit dem Löffel gefüttert werden muß.
R. Max schrieb:> Klaus Wachtler schrieb:>> PS: Weil sonst das ## nicht funktioniert>> Habs eben getestet und bekomme vom Präprozessor den gleichen Output,> egal ob ich SBIT oder SBIT_ verwende (gcc 4.6.2).
Mag sein, daß es nicht mit allen Compilern nötig ist (ggf. nur bei
älteren).
Ich kann mich dunkel erinnern, daß ich so eine Konstruktion vor ein paar
Jahren auch brauchte. Vielleicht hat es sich erledigt.
Hans Gruber schrieb:> Wenn du mir diesen Teil jetzt noch kurz erklären könntest wärs göttlich> von dir. :-)
Hier kannst du übrigens die Entstehungsgeschichte der von Peter
geposteten Methode nachlesen:
Byte als Bitfelder darstellen:
Beitrag "attribute packed"
Mappen dieser Darstellung auf ein I/O-Register:
Beitrag "Re: #define in C"Beitrag "Re: sbit macro für avr-gcc"
Und schließlich noch ein Convenience-Makro drumherum:
Beitrag "Re: sbit macro für avr-gcc"R. Max schrieb:> Gibt es einen bestimmten Grund für diese Indirektion?> #define SBIT(x,y) SBIT_(x,y)
Ja. Wenn du dem SBIT-Makro als zweites Argument keine Zahl, sondern ein
weiteres Makro übergibst, also z.B.
1
#define TIMSK_TOIE0 SBIT(TIMSK, TOIE0)
dann funktioniert die korrekte Expansion nur mit dem Zwischenschritt
über SBIT_(). Das hängt mit der Reihenfolge zusammen, in der der
C-Präprozessor Makroargumente expandiert.