Forum: Compiler & IDEs #define.....


von Tipper (Gast)


Lesenswert?

Meine Lernphase in Sachen C-Programmierung ist soeben
jäh unterbrochen worden.

Ich stolperte über folgende Anweisung:

  #define ASC1_IBUF   (*(( uword volatile * ) 0xFEB8

Wie ist diese Anweisung als Ganzes zu verstehen? Das was ich heraus lese 
ist: Das Word-Register ASC_IBUF liegt an der Addesse 0xFEB8.

Vielleicht kann mir jemand auf die 'Sprünge' helfen.

von Joerg Wunsch (Gast)


Lesenswert?

Diese Anweisung ist gar keine wirkliche Anweisung, sondern
ein sogenannter Präprozessormakro.  (Präprozessor deshalb,
weil dieser vor dem eigentlichen Compilieren über das
Programm geschickt wird, um include-Dateien einzusammeln
und eben derartige Makros aufzulösen.)

Makro heißt dabei, daß das Wort direkt nach #define der
Name des Makros ist, alles was danach steht, wird dessen
Definition.  Wann immer später im Programm ASC1_IBUF
auftaucht, wird der komplette Ausdruck der rechten Seite
an dieser Stelle stattdessen eingefügt (macro expansion).

Die andere Frage ist, was das Stückchen Code dann wohl
an dieser Stelle tun wird.  Es muß irgendwo eine Typdefinition
(oder einen weiteren Makro) für "uword" geben, vermuten
wir mal, es handelt sich dabei um eine 16-bit Ganzzahl
ohne Vorzeichen (unsigned int).  Der Ausdruck in den
inneren Klammern ist ein sogenannter typecast, also eine
zwangsweise Typumwandlung, in diesem Falle auf einen
Zeiger auf eine solche Zahl.  Zusätzlich wird der Compiler
angewiesen, bei Zugriffen über diesen Zeiger keine
Optimierungen durchzuführen, d. h. jedesmal, wenn der
Ausdruck geschrieben steht, muß der Zugriff erneut
ausgeführt werden.  Dies macht man typischerweise, wenn
der entsprechende Wert außerhalb des ,,Blickfeldes'' des
Compilers manipuliert worden sein kann.  Im vorliegenden
Fall würde ich darauf tippen, daß bei Zugriff auf diese
Adresse externe Hardware angesprochen wird (memory-mapped
IO).  Ein anderer typischer Fall für volatile wären
Variablen, die aus einer Interruptroutine heraus
geändert werden sollen.

Schließlich noch der letzte * vor dem typecast: damit wird
der Compiler angewiesen, den Inhalt des entsprechenden
Zeigers zu erfragen, in diesem Falle also der (vermutlich)
16-bit Zahl, die an Adresse 0xFEB8 zu finden ist.

Allerdings ,,zieht'' es in Deinem Beispiel ganz mächtig...
Da fehlen zwei schließenden Klammern.

von Tipper (Gast)


Lesenswert?

Heissa und Ole,

besten Dank für Deine professionelle Erklärung!

Ja, Du hast Recht. 'uword' steht für 'unsigned word'.

Diese Pp-Anweisung wird für einen 16-Biter benötigt.

ASC1_IBUF ist der Input-Buffer der USART1.

Das mit dem 'Durchzug' hab' ich übersehen, sorry.

Besten Gruß   Tipper

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.