mikrocontroller.net

Forum: Compiler & IDEs Anweisungsverhalten von printf() unter WinAVR


Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

ich lese immer in irgendwelchen Büchern von der Verwendeung des 
"printf();" Befehls. Aber ich kapiere die Funktionsweise nicht so 
wirklich... :o(

Der eine verwendet die Funktion zur Ausgabe auf der seriellen 
Schnittstelle, der ander schiebt damit Daten zum LCD, usw. . Ich meine 
ich habe den printf- Befehl schon zur Ausgabe von Daten auf der 
seriellen Schnittstelle von einem 8051 Controller verwendet, aber wie 
kann ich dem Compiler sagen das er den Befehl jetzt garnicht für diese 
Anwendung nutzen soll, sondern Daten auf dem LCD ausgeben soll... Ich 
schnalle das nicht!!

Z.B. habe ich mir die Bücher von Michael Baldischweiler für C51 von Keil 
gekauft und gelesen. Dort verwendet er die Funktion erst zur Ausgabe auf 
der seriellen Schnittstelle und nachher spricht er mit der Funktion das 
LCD an!! Er hat aber nichts davon geschrieben, dass er diese angepasst 
hat. Geht das, und wie? Ich kapiere das nicht.... bin blöd ;o)

Gruß
Benjamin

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
printf benutzt zur Ausgabe eine vom Anwender zur Verfügung zu stellende 
Funktion. Wie die heißt, ist von Compiler zu Compiler unterschiedlich; 
bei manchen Systemen wird auch eine Default-Implementierung 
mitgeliefert, die beipielsweise die serielle Schnittstelle anspricht.

Diese Funktion wird für jedes auszugebende Zeichen einmal aufgerufen und 
könnte beispielsweise putc oder putchar heißen.

Näheres steht in der Dokumentation des verwendeten Compilers.

Autor: Günter R. (galileo14)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du verwendest besser die "f"-Funktionen wie "fprintf", "fputs" etc; dazu 
benötigst Du noch z.B. "fdev_setup_stream", um die Devices zu 
spezifizieren. Du kannst damit mehrere "File-Control-Blocks" definieren. 
Dann kannst Du ganz genau steuern, wohin welche Deiner Ausgaben gehen 
sollen; das mache ich schon seit langer Zeit so. Im avr-libc-Manual ist 
beschrieben, wie das geht.

Günter

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktionen wie printf, puts, scanf etc. verwenden als low-level alle
putch() oder getch(), je nach Datenrichtung.
Du musst diese Funktionen (meistens putch() für printf) überschreiben. 
Wie das geht, kann man den jeweiligen Compiler Manuals entnehmen.

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso, Du suchst speziell nach WinAVR, also GCC:

int uart_putchar(char c, FILE *stream);

static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, 
_FDEV_SETUP_WRITE);

int uart_putchar(char c, FILE *stream)
{
  while( !( UCSR0A & (1<<UDRE0)));
  UDR0 = c;

  return 1;
}

Und in der Initialisierung einfach noch:

stdout = &mystdout;      // Umlenkung!!


Somit wird die obige uart_putchar() als stdout verwendet, also von 
printf etc.

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Erklärungen auf das Wesentliche geschrumpft:

Funktional kannst du dir printf so vorstellen...

Pseudocode:

int printf(char *fmt, ...)
{
   return (fprintf(stdout, fmt, ...));
}

Und stdout kannst du beliebig umdefinieren/umprogrammieren.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thorsten wrote:

> Du musst diese Funktionen (meistens putch() für printf)
> überschreiben.  Wie das geht, kann man den jeweiligen Compiler
> Manuals entnehmen.

Wenn du's nicht genau weißt, dann schreibe bitte lieber nichts dazu.

avr-libc kenn kein putch() oder getch().

Der Weg, wie man bei avr-libc die low-level-IO-Funktionen an einen
Stream bindet, steht in der Doku und wurde ja dann hier auch noch
explizit erwähnt.

Man kann auf diese Weise beliebig viele Streams haben, die auf
verschiedene Geräte zugreifen können (UART, LCD, I²C, ...).  Man kann
bei Bedarf auf stdout während der Laufzeit zwischen verschiedenen
Streams hin- und herschwenken.  Damit geht printf() dann auf
unterschiedliche Geräte, wobei man mit fprintf() jedes Einzelne immer
explizit ansprechen kann.

Autor: Josef Kkk (zumlin)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe das gleiche Problem wie oben beschrieben nur bei mir ist die 
gcc-avr 4.1.0 (System: Ubuntu Edgy) installiert bzw mit der wird 
compiliert.

-------- begin --------
avr-gcc (GCC) 4.1.0
[...]

Ich habe aber das gcc-avr packet bereits installiert und es scheint auch 
auf dem neuesten Stand zu sein. Warum habe ich dann nur die 4.1.0?
Linux ist leider immer noch zu sehr ein spanisches Dorf für mich. ;)

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.