Forum: Compiler & IDEs printf zweimal


von Richard W. (richi)


Lesenswert?

Hallo

es geht um einen Atmega324PA.
Dieser hat 2 Uarts.
Wie kann ich nun für jeden Uart eine eigene printf Funktion erstellen.

Bisher habe ich nur einen Uart gebraucht, da habe ich es folgendermaßen 
gemacht:

  fdevopen (uart_putc, 0);



Viele Grüße
Richi

von Uwe (de0508)


Lesenswert?

Hallo Richi,

verwende kein printf.

Chan hat da einige schöne Libs im Netz:

* http://elm-chan.org/fsw/strf/xprintf.html

Ich verwende dann 2 mal diese Lib:

"Embedded printf module for AVR"
* http://elm-chan.org/docs/avrlib/xitoa.zip

Weitere Anregungen findest Du hier:

Beitrag "Re: [S] "selfmade" sprintf()- Funktion:)"

und hier etwas von PeDa:

"Formatierte Zahlenausgabe in C"
* Beitrag "Formatierte Zahlenausgabe in C"

von Peter D. (peda)


Lesenswert?

Es gibt 2 Ansätze.

1.
Du benutzt sprintf und schreibst auf einen Puffer, den Du der UART0 oder 
UART1 übergibst.

2.
Du definierst eine Variable, die zwischen UART0 und 1 umschaltet.
1
uint8_t uselect = 0;
2
3
void putchar( char c )
4
{
5
  switch( uselect ){
6
    case 0: putchar0( c ); break;
7
    case 1: putchar1( c ); break;
8
  }
9
}

Die einzelnen UART-Funktionen (init_uart0, putchar0, getchar0 usw.) mußt 
Du für beide UARTs bereitstellen.


Peter

von Stefan E. (sternst)


Lesenswert?

Peter Dannegger schrieb:
> Es gibt 2 Ansätze.
>
> 1.
> Du benutzt sprintf und schreibst auf einen Puffer, den Du der UART0 oder
> UART1 übergibst.
>
> 2.
> Du definierst eine Variable, die zwischen UART0 und 1 umschaltet.

3.
Du benutzt fprintf.
1
FILE *uart0 = fdevopen (uart0_putc, 0);
2
FILE *uart1 = fdevopen (uart1_putc, 0);
3
4
fprintf (uart0, "Hallo Null!");
5
fprintf (uart1, "Hallo Eins!");

von Richard W. (richi)


Lesenswert?

Hallo

erstmal danke für eure Hilfe.
Ich habe jetzt meinen ganzen Code mit den elm-chan-Bibliotheken 
ausgestattet. Dann habe ich folgendes gemacht:

#define uart0_printf( xfprintf(uart0_putc,

nun kommt aber die Fehlermeldung

Fehler  1  "(" may not appear in macro parameter list

wie kann ich diesen Fehler beheben?

von Rolf M. (rmagnus)


Lesenswert?

Am besten keine Klammer in eine Makro-Parameterliste schreiben ;-)

Die Frage ist, was diese Klammer
1
#define uart0_printf( xfprintf(uart0_putc,
2
                    ^

da sucht. Sie öffnet die Parameterliste von uart0_printf, also gehört 
alles, was dahinter bis zur schließenden Klammer (die bei dir fehlt) 
kommt, sind Paramter.

von Rolf M. (rmagnus)


Lesenswert?

Ok, ich glaube, ich habe eine Idee, was dein Ansinnen war. Probier's mal 
damit:
1
#define uart0_printf(...) xfprintf(uart0_putc, __VA_ARGS__)

von Richard W. (richi)


Lesenswert?

Danke Rolf. Genau das habe ich gesucht, man lernt nie aus.

Jetzt hätte ich noch eine konkrete Frage zu der verwendeten Bibliothek.
Diese fordert von der putc-Funktion als Übergabeparameter ein 
unsigned-char. Bisher habe ich und ich will dass es auch so bleibt immer 
ein char übergeben. Muss ich eine extra Funktion erstellen oder kann man 
da einen einfachen Trick (cast, ich weiß nur nicht wo) anwenden?

Gruß
Richi

von Richard W. (richi)


Lesenswert?

Ich habe mir jetzt eine extra Funktion für unsigned-chars erstellt.

@Rolf:

Mir ist dazu noch eine Frage eingefallen.
Ich mache fogendes:
#define abc(__s, ...) abcde(__s, _VA_ARGS_)

Wenn _VA_ARGS_ leer ist, also keine zusätzlichen Parameter mit 
übergeben werden, kommt eine Fehlermeldung, weil auf das Komma die 
Klammer folgt.

Wie kann ich das umgehen.

Meine Idee, ein extra Define funktioniert auch nicht:
#define abc(__s) abcde(__s)

Gruß
Richi

von Rolf M. (rmagnus)


Lesenswert?

Warum übergibst du __s nicht einfach als Teil der VA_ARGS statt als 
eigenen Parameter? Dann ergibt sich das Problem nicht.

von Diplomtroll (Gast)


Lesenswert?

Richard W. schrieb:
> Mir ist dazu noch eine Frage eingefallen.
> Ich mache fogendes:
> #define abc(__s, ...) abcde(__s, _VA_ARGS_)
>
> Wenn _VA_ARGS_ leer ist, also keine zusätzlichen Parameter mit
> übergeben werden, kommt eine Fehlermeldung, weil auf das Komma die
> Klammer folgt.
>
> Wie kann ich das umgehen.

Der GCC kann alles, man muss nur die Doku lesen:

>Second, the `##' token paste operator has a special meaning when placed
>between a comma and a variable argument. If you write

>     #define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

>and the variable argument is left out when the eprintf macro is used, then
>the comma before the `##' will be deleted. This does not happen if you
>pass an empty argument, nor does it happen if the token preceding `##' is
>anything other than a comma.
http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

von Richard W. (richi)


Lesenswert?

Danke, genau das habe ich gesucht.

Gruß
Richi

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.