mikrocontroller.net

Forum: Compiler & IDEs printf für andere Funktionen


Autor: Patrick B. (p51d)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo miteinander

Ich habe einmal eine kleine Frage, ob es möglich ist, die 
Printf-Funktion auch für andere C-Funktionen zu nützen?

Damit man bequem zum Beispiel ein LCD ansteuern könnte, oder ein 
Ringbuffer für eine Kommunikation "bedienen"...

Ich dachte, dass ich schon mal so etwas gesehen hätte:
void lcd_putc(char c){
//
}
printf(lcd_putc,"Hallo Welt: %d\n",datum);

Gibt es so etwas schon oder wie müsste das aussehen?

Besten Dank für die Hilfe
MFG
Patrick

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick B. schrieb:
> Hallo miteinander
>
> Ich habe einmal eine kleine Frage, ob es möglich ist, die
> Printf-Funktion auch für andere C-Funktionen zu nützen?

Möglich (beim gcc) schon.
Aber dazu muss man eine Ausgabefunktion für Einzelzeichen unter das 
printf in das I/O System für den Ausgabe-Stream einschmuggeln

> Damit man bequem zum Beispiel ein LCD ansteuern könnte, oder ein
> Ringbuffer für eine Kommunikation "bedienen"...
>
> Ich dachte, dass ich schon mal so etwas gesehen hätte:
>
> void lcd_putc(char c){
> //
> }
> printf(lcd_putc,"Hallo Welt: %d\n",datum);
> 

So höchst wahrscheinlich nicht.

Wenn da eine zusätzliches Argument beim 'printf' war, dann war das 
höchst wahrscheinlich
  char buffer[30];
  sprintf( buffer, "Hallo Welt: %d\n", datum );
  lcd_puts( buffer );

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick B. schrieb:
> Ich habe einmal eine kleine Frage, ob es möglich ist, die
> Printf-Funktion auch für andere C-Funktionen zu nützen?

printf ist eine Funktion aus der Standard-library, und alles 
wissenswerte dazu steht in der der Doku zu der von dir benutzten 
Version.

Falls du zufällg AVR's progrtammierst, und das auch noch zufällig mit 
avr-gcc und der avr-libc machst, dann geht das. Wie, steht in der 
avr-libc-Doku zu printf.

Oliver

Autor: Andreas Schweigstill (Firma: Schweigstill IT) (schweigstill) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sprintf() schreibt aber nur in einen Puffer, der dem aufrufenden 
Programm gehört. Mittels fprintf() kann man jedoch in verschiedene 
Ausgabedateien bzw. -datenströme schreiben. Ursprünglich bei unixoiden 
Betriebssystemen, aber mittlerweile durchaus auch allgemein 
gebräuchlich, sind die Dateideskriptoren 0-2 für Standardausgabe, 
Standardeingabe und Standardfehlerkanal (stdout, stdin, stderr) 
reserviert. "Echte" Dateideskriptoren besitzen dann höhere Kennungen.

Um eine Ausgabeumlenkung zu realisieren, sollte man in den Quelltext der 
C-Bibliothek schauen. Dann kann man schnell entscheiden, ob man z.B. 
einen eigenen Handler für stderr realisiert oder zusätzliche Geräte 
"erfindet".

Ggf. befinden sich in den Beschreibungen zu 
Compiler/Standardbibliotheken auch schon entsprechende Hinweise oder 
Anleitungen, wie eine Anpassung der Ein-/Ausgabekanäle erfolgen kann.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick B. schrieb:
> Hallo miteinander
>
> Ich habe einmal eine kleine Frage, ob es möglich ist, die
> Printf-Funktion auch für andere C-Funktionen zu nützen?
>
> Damit man bequem zum Beispiel ein LCD ansteuern könnte, oder ein
> Ringbuffer für eine Kommunikation "bedienen"...
>
> Ich dachte, dass ich schon mal so etwas gesehen hätte:
>
> void lcd_putc(char c){
> //
> }
> printf(lcd_putc,"Hallo Welt: %d\n",datum);
> 
>
> Gibt es so etwas schon oder wie müsste das aussehen?

Falls du die avr-libc verwenden willst/kannst kann man sich nen eigenens 
stdout bauen so wie beschrieben in

http://www.nongnu.org/avr-libc/user-manual/group__...

Damit kommt printf allerdings nur mit dem Standardumfang. Funktionalität 
wie wie zB Cursor-Positionierung, Display löschen etc. sind da nur 
holprig unterzubringen.

Autor: Patrick B. (p51d)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Neu-Definition von der Stream-Funktion beim AVR GCC kenne ich, aber 
ich habe das noch nie für eine andere Funktion gesehen.

Bei einem CCS-Compiler für PIC's in der Schule habe ich diese 
möglichkeit gesehen, und auch schon angewendet.

Momentan versuche ich mich gerade an einem HI-Tech Compiler, aber leider 
habe ich da nicht viel in der Doku (immerhin >450 Seiten) gesehen.
in den Header-Files habe ich nur volgendes gefunden:
extern char *  gets(char *);
extern int  puts(const char *);
extern int  scanf(const char *, ...);
extern int  sscanf(const char *, const char *, ...);
extern int   vprintf(const char *, va_list);
extern int  vsprintf(char *, const char *, va_list);
extern int  vscanf(const char *, va_list ap);
extern int  vsscanf(const char *, const char *, va_list);

#pragma  printf_check(printf) const
#pragma  printf_check(sprintf) const
extern int sprintf(char *, const char *, ...);
extern int printf(const char *, ...);

Soweit ich weiss, ist der CCS nicht immer Regelkonform.

Könnte man so eine Funktion auch selber schreiben?

MFG
Patrick

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick B. schrieb:

> Momentan versuche ich mich gerade an einem HI-Tech Compiler, aber leider
> habe ich da nicht viel in der Doku (immerhin >450 Seiten) gesehen.
> in den Header-Files habe ich nur volgendes gefunden:
>
> extern char *  gets(char *);
> extern int  puts(const char *);
> extern int  scanf(const char *, ...);
> extern int  sscanf(const char *, const char *, ...);
> extern int   vprintf(const char *, va_list);
> extern int  vsprintf(char *, const char *, va_list);
> extern int  vscanf(const char *, va_list ap);
> extern int  vsscanf(const char *, const char *, va_list);
> 
> #pragma  printf_check(printf) const
> #pragma  printf_check(sprintf) const
> extern int sprintf(char *, const char *, ...);
> extern int printf(const char *, ...);
> 
>
> Soweit ich weiss, ist der CCS nicht immer Regelkonform.

Solche Sachen sind nie 'regelkonform', vor allen Dingen deshalb nicht, 
weil der C-Standard nicht fordert, das du das machen kannst.


> Könnte man so eine Funktion auch selber schreiben?

Man könnte.
Siehe zb hier
Beitrag "AVR32 printf umleiten stdout"

Allerdings hat man dann einen fix dimensionierten Buffer drinnen, den 
man da eigentlich nicht haben möchte.

Meiner Meinung nach, wird die Möglichkeit printf direkt auf einem 
'Gerät' benutzen zu können, auf µC überschätzt. Das bringt viel weniger 
als man sich erwartet oder auf einem Desktop System zur Verfügung hat. 
Hauptsächlich deshalb, weil man meistens sowieso Spezialfunktionalität 
benötigt, um zb den Cursor irgendwo hin zu schicken.

Und den Rest kann man auch mit einer guten String-Ausgabefunktion und 
Funktionen zur Konvertierung von Zahlen in Strings gut und vor allen 
Dingen resourcenschonend erledigen. Muss man nicht auf Speicher und 
Laufzeit achten, und hat man eine gute Verwendung für die 
Formatiermöglichkeiten, die einem die ...printf() Familie bietet, ist 
auch sprintf eine nicht allzuschlechte Möglichkeit.

Autor: Patrick B. (p51d)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe das jetzt über sprintf gelöst:
void lcd_write(char *i_string){

  while(*i_string!=0){
    lcd_putc(*(i_string++));
  }
  __delay_ms(1);
}

sprintf(lcd_string_buf,"\fConnected with PC\nWaiting for command\n/data");
lcd_write(lcd_string_buf);

Funktioniert eigentlich soweit so gut.

MFG
Patrick

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick B. schrieb:

> sprintf(lcd_string_buf,"\fConnected with PC\nWaiting for
> command\n/data");
> lcd_write(lcd_string_buf);

Wozu brauchst du ganz konkret bei dieser einen Ausgabe den sprintf?
  lcd_write( "\fConnected with PC\n"
             "Waiting for command\n"
             "/data" );

lcd_write gibt einen String aus.
Du hast einen String.

Autor: Patrick B. (p51d)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich direkt einen String ind die Funktion lcd_write geschrieben 
habe, bekam ich eine Fehlermeldung wegen eines ungültigen Pointer-Typs.
über eine Array habe ich dann keine Fehlermeldung mehr bekommen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick B. schrieb:
> Wenn ich direkt einen String ind die Funktion lcd_write geschrieben
> habe, bekam ich eine Fehlermeldung wegen eines ungültigen Pointer-Typs.
> über eine Array habe ich dann keine Fehlermeldung mehr bekommen.

Ich vergass. Du benutzt ja keinen gcc.
Höchst wahrscheinlich benutzt dein Compiler für konstante Texte einen 
anderen Speicherort und darum musst du den Umweg gehen.

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.