mikrocontroller.net

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


Autor: Tipper (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tipper (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.