#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

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.