Fragen zur Funktion printf()

Hallo!

Ich will die Funktion printf() benutzen, um bei einem Mikrocontroller Daten über den USART (serielle Schnittstelle) auszugeben. Die Daten müssen also ins Transmit-Buffer gelangen. Damit verbindet sich die Frage, wie ich das der Funktion bzw. dem Compiler klar mache. Von dem bißchen C-Programmieren, das ich am PC gemacht habe, weiß ich nur, dass bei printf() normalerweise die Standardausgabe adressiert wird und das ist der Monitor. Warum das so ist und wie man das ändern kann, darüber habe ich mir bislang noch keine Gedanken gemacht. Beim PC hängt zudem das Betriebssystem dazwischen, bei meinem Mikrocontrollerprogramm nicht.
Also erste Frage: Wodurch wird bestimmt, wohin printf() die Daten schreibt?

Die an der seriellen Schnittstelle ausgegebenen Daten sollen natürlich von einem anderen Gerät empfangen werden. Dazu möchte ich wissen, was denn nun genau auf der Leitung liegt. Ich weiß, dass der USART Zeichen sendet und dass prinft() die Funktion putchar aufruft, die Zeichen ausgibt. Soweit passt das also. Heißt aber, das printf() wohl irgendwie beliebige elementale Datentypen (int, float) in Zeichen (char) umwandelt. Aber wie sieht das aus? Wenn ich z.B. den Integer 2318 ausgebe, sendet der USART dann hintereinander die Zeichen ‚8‘, ‚1‘, ‚3‘, ‚2‘? Und was ist, wenn es sich um einen float-Typ hadelt, z.B. die Zahl 23,65? Kommen da wirklich nur die Zeichen, die man am Ende sieht, und in der richtigen Reihenfolge?
Also zweite Frage: Welche Zeichen macht printf() aus den verschiedenen elementaren Datentypen?

Danke im Voraus.

Hi,

Du kannst sprintf benutzen, um in einen String (char-Buffer) zu schreiben oder fprintf, um in ein geöffnetes File-Handle zu schreiben. Wie würdest Du denn normalerweise Zeichen an die serielle Schnittstelle übertragen? Soweit ich mich erinnere, kann man sie als File ansprechen.

Gruß, Lutz

Hallo Fragewurm,

Von dem bißchen
C-Programmieren, das ich am PC gemacht habe, weiß ich nur,
dass bei printf() normalerweise die Standardausgabe adressiert
wird und das ist der Monitor. Warum das so ist und wie man das
ändern kann, darüber habe ich mir bislang noch keine Gedanken
gemacht.

Kommt jetzt drauf an, wie deine Bibliothek genau aufgebaut ist.

Im Prinzip musst du putchar(), oder wie das Teil bei deiner Bibliothek genau heisst, selber schreiben, sodass es die Zeichen an das UART endet.

Beim PC hängt zudem das Betriebssystem dazwischen,
bei meinem Mikrocontrollerprogramm nicht.
Also erste Frage: Wodurch wird bestimmt, wohin printf() die
Daten schreibt?

printf() ruft eigentlich fprintf() auf, dabei wird dann als FILE* stdout übergeben. An Stelle von putchar() wird igentlich fputc() augerufen.
Soweit der Standard, kann aber be deiner Bibliothek anders laufen.

Normalerweise zeigt FILE* auf eine Structur welche die Daten enthält, welche zur Verwaltung einer Daei und der Ansteuerung der Laufwerke usw. benötigt werden.
Wenn man aber z.B. nur zei UARTs vewalten muss, kann man einfach die Werte 1 und 2 vewenden ud braucht gar nicht wirklich einen Zeige auf eine Structur.

Dazu
möchte ich wissen, was denn nun genau auf der Leitung liegt.
Ich weiß, dass der USART Zeichen sendet und dass prinft() die
Funktion putchar aufruft, die Zeichen ausgibt. Soweit passt
das also. Heißt aber, das printf() wohl irgendwie beliebige
elementale Datentypen (int, float) in Zeichen (char)
umwandelt.

Im Prinzip JA,
aber putchar() ist eigentlich ein Macro welches dann putc() oder fputc() aufruft.

Aber wie sieht das aus? Wenn ich z.B. den Integer
2318 ausgebe, sendet der USART dann hintereinander die Zeichen
‚8‘, ‚1‘, ‚3‘, ‚2‘?

Also printf() ruft nur putc() auf, dass das beim UART raus kommt ist deine Aufgabe…

Und was ist, wenn es sich um einen
float-Typ hadelt, z.B. die Zahl 23,65? Kommen da wirklich nur
die Zeichen, die man am Ende sieht, und in der richtigen
Reihenfolge?

Genau, putc() hat ja keie Ahnung was da raus soll und kann nur ein einzelnes Zeichen ausgeben.

Welche Funktion di genau anpassen musst, sollte im Handbuch zum Compiler irgndwo stehen. Manchmal auc irgendwo in einer Daei auf der Festplatte.
Wenn du genau angeben würdest, welchen Compiler du verwendest (Herseller und Version) könnte man konkreter werden.

MfG Peter(TOO)

Hallo Entikulo !

Auf die serielle Schnittstelle greifst du wie auf eine Datei zu:
Zuerst öffnen:
Handle = CreateFile(„COM1“, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, 0);
Dann die COM-Parameter setzen mittels SetCommState().
Dann mittels WriteFile() und ReadFile() schreiben bzw. lesen.
Statt printf() würde ich wie geraten sprintf() verwenden um die gewünschten Zeichen in einen String zu schreiben und diesen dann mit WriteFile() schreiben. (Du könntest aber auch mittels fdopen() einen Filepointer aus dem Filehandle holen und dann mit fprintf() darauf schreiben).

mfg
Christof

Hallo Christof,

Dir ist aber schon klar, dass CreateFile(), SetCommState(), WriteFile() und ReadFile() Aufrufe an das Betribssystem sind und nicht in C implemntiert sind?

Und da der UP eben einen nackten MicroController ohne Betriebssystem programmieren will?

MfG Peter(TOO)

Hi,

das ist leider ein wenig unspezifisch. Zum versenden von Daten über USART gibts keinen Standard. Was benutzt du denn für einen MC?

BTW: ist es eigentlich immer eine schlechte Idee auf einem MC printf nutzen zu wollen, weil das ewig viele Resourcen frisst.

Grüße,

Hallo FRagewurm,

BTW: ist es eigentlich immer eine schlechte Idee auf einem MC
printf nutzen zu wollen, weil das ewig viele Resourcen frisst.

Das kommt sehr auf den Compiler an, also den Heteller.

Bei IAR gibt es mehrere Vesionen von printf(), z.B. ohne float, damit die Bibliothek nicht eingebunden wird.

Dann gibts auch noch Tricks um den, noralerweise nötigen, Zeilenpuffer zu eliminieren.

MfG Peter(TOO)