#define Ich bekomme ein Makro nicht hin.

OP #4553484
Lesenswert?

Guten Morgen,

ich glaube ich bin zu doof - oder es geht einfach nicht - !!! (aber eher 
glaube ich, ich bin zu doof und sehe vor lauter Bäumen den Wald nicht).

Problem:

Ich habe mir eine eigene sehr minimalistische printf Funktion 
geschrieben damit ich den printf-Komfort auch mit einem ATtiny2313 
"geniese" (siehe Code).

Funktioniert alles tadellos wie ich mir das wünsche ... mit einer 
Ausnahme.
Da der Tiny nur extrem spärliche 128 Byte RAM hat, muß ein String für 
printf zwingend im Codespeicher abgelegt sein und dann (das ist das 
üble) mittels "pgm_read_byte" dort wieder hervor geholt werden.

Der für mich größte Schönheitsfehler besteht nun darin, dass ich meine 
printf Funktion nun folgendermaßen aufrufen muß:
1
tiny_printf(PSTR("Zahlensystem        %dd  = %xh\n\r"),84, 84);

Das gefällt mir so gar nicht.
Ich hätte gerne ein Makro, welches mir den Aufruf umdefiniert, damit ich 
bspw. folgendes schreiben kann:
1
my_printf("Zahlensystem        %dd  = %xh\n\r",84, 84);

Also irgendwas im Stile von:
1
#define my_printf( bla bla     tiny_printf(PSTR( bla bla

... eben ohne das lästige PSTR( ... und das schlimme: die schließende 
Klammer nach dem String.

Bin ich zu dämlich oder geht das wirklich nicht ?
Angehängte Dateien:
Gast #4553521
Lesenswert?

PS:
1
void tiny_printf(const uint8_t *s,...)
2
{
3
  int       total, arg1;
4
  uint8_t   token, *arg2;
5
  char      ch;
6
  va_list   ap;
Die 90er sind vorbei, man darf Variablen heutzutage auch woanders als am 
Funktionsanfang deklarieren. Am sinnvollsten ist es, die Variable genau 
dort zu deklarieren, wo sie auch das erste Mal benutzt wird, z.B.:
1
uint8_t token= pgm_read_byte(++s);
2
switch(token) ...
So ist genau klar, in welchen Bereich die Variable überhaupt benutzt 
wird (nämlich innerhalb des if-Blocks). Man kann sie auch nicht 
versehentlich auslesen, während sie noch überhaupt keinen Wert hat.

Dein Algorithmus ist ineffizient, hier:
1
if(pgm_read_byte(s)=='%')
und hier:
1
uart_putchar(pgm_read_byte(s));
und hier:
1
ch= pgm_read_byte(s);
liest  du exakt das selbe Zeichen immer wieder ein indem du 
pgm_read_byte mit dem selben Parameter aufrufst. Nimm doch die Variable 
"ch", um das Zeichen zwischenzuspeichern... Außerdem musst du im letzten 
Stück das "s++" und das uart_putchar(...) tauschen!
#4553686
Lesenswert?

Spasshalber mal ein putint() ohne mult und div:
1
void putint(int i)
2
{
3
    static int zz[] = { 10000, 1000, 100, 10 };
4
    bool_t not_first = FALSE;
5
    
6
    if (!i)
7
    {
8
        uart_putchar('0');
9
    } else {
10
        if(i < 0)
11
        {
12
            uart_putchar('-');
13
            i = -i;
14
        }
15
        
16
        int z, b;
17
        for(int zi = 0; zi < 4; zi++}
18
        {
19
            z = 0;
20
            b = 0;
21
            
22
            while(z + zz[zi] <= i)
23
            {
24
                b++;
25
                z += zz[zi];
26
            }
27
            
28
            if(b || not_first)
29
            {
30
                uart_putchar('0' + b);
31
                not_first = TRUE;
32
            }
33
            
34
            i -= z;
35
        }
36
        uart_putchar('0' + i);
37
    }
38
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren