Guten Morgen zusammen, ich verwende ein HD44780 kompatibles Display an einem Atmega32. Auf dem Display möchte ich die Uhrzeit anzeigen. Als LCD-Bibliothek verwende ich die von Peter Fleury. Die funktioniert auch einwandfrei. Mein Problem liegt eher bei der itoa Funktion, die AVR-GCC mitbringt. Solange die Stellen für Sekunden, Minuten oder Stunden einstellig sind, ist der ausgegebene String auch nur einstellig. Das ist natürlich unschön, wenn die Einer zuerst auf der Zehnerstelle stehen und erst bei Zahlen >9 auf Ihre eigentliche Stelle rücken. Gibt es da eine elegante Möglichkeit, dem String eine führende 0 zu verpassen?
Über Eleganz kann man natürlich streiten, aber spontan fällt mir sowas ein:
1 | puffer[0] = '0'; |
2 | itoa( minuten, puffer+( minuten<=9 ), 10 ); |
Der Rückgabewert von itoa() ist dann natürlich nicht mehr unbedingt der eigentliche Stringanfang.
MarioG schrieb: > Gibt es da eine elegante Möglichkeit, dem String eine führende 0 zu > verpassen? sprintf() ? MfG Klaus
Klaus Wachtler schrieb: > Über Eleganz kann man natürlich streiten, aber spontan fällt mir sowas > ein: Irgendwie kommtja auch noch der ':' in die Uhrzeit mit rein. Und das wird auch nicht anders sein.
Für eine enizelne Zahl würde ich eventuell auch itoa nehmen. Wenn Flash-Platz kein Problem ist, würde ich aber gleich sprintf nehmen. Ist einfach komfortabler, weil man da die komplette Uhrzeit in einem Aufwasch formatieren lassen kann sprintf( buffer, "%02d:%02d:%02", stunden, minuten, sekunden ); lcd_puts( buffer ); fertig. Ein bischen Overhead ist mir dann der Komfort schon wert.
> Irgendwie kommtja auch noch der ':' in die Uhrzeit mit rein. Und das > wird auch nicht anders sein. nicht unbedingt, den Doppelpunkt kann man ja einmal ausgeben und muß ihn nicht laufend aktualisieren. Insofern braucht man ihn nicht im String mit der Zahl.
Klaus Wachtler schrieb: > nicht unbedingt, den Doppelpunkt kann man ja einmal ausgeben und muß ihn > nicht laufend aktualisieren. > Insofern braucht man ihn nicht im String mit der Zahl. Ob das positionieren des LCD-Cursors auf das jeweilige Zahlenfeld schneller ist, als immer den ganzen String auszugeben ... ? MfG Klaus
Auf einem Mega32 kann man ja nicht viel falsch machen, da wird jede Lösung gehen; siehe die pragmatische Variante von Karl-Heinz B.. Insofern kann man lange sinnlos um die beste Variante streiten.
Hallo, Man kann auch ein eigenes itoa benutzen. Puffer muss 8 Zeichen lang sein. Temp = stunden / 10; Puffer[0] = Temp + '0'; Temp = Stunden - 10*Temp;//== stunden % 10 Puffer[1] = Temp + '0'; Puffer[2] = ':'; // Braucht nur einmal sein Temp = minuten / 10; Puffer[3] = Temp + '0'; Temp = minuten - 10*Temp; Puffer[4] = Temp + '0'; Puffer[5] = ':'; // Braucht nur einmal sein Temp = sekunden - 10*Temp; Puffer[6] = Temp + '0'; Puffer[7] = 0; // Braucht nur einmal sein Und es gibt sicher noch tausende Varianten ;-)
Vielen Dank schonmal für die zahlreichen Antworten! Meine Frage zielte ja schon eher in die Richtung, das hauseigene itoa zu verwenden, ab. Vom Komfort her gefällt mir die Version mit sprintf dann doch schon am besten. Ich werde das mal austesten und dann berichten. (wird aber vor morgen nicht passieren, da ich jetzt weg muß...)
MarioG schrieb: > Vielen Dank schonmal für die zahlreichen Antworten! > Meine Frage zielte ja schon eher in die Richtung, das hauseigene itoa zu > verwenden, ab. Wenn du sowieso eine hauseigene itoa Lösung hast, ist es am besten sich mit dem Systemprogrammierer kurzzuschliessen und ihn um eine Spezialversion zu bitten. Denn für itoa bedeutet die Forderung keine führenden 0-en zu erzeugen Aufwand. Damit bist du in der paradoxen Situation, dass itoa erst Aufwand betreibt um die führenden 0-en wegzukriegen und du hinten nach Aufwand betreibst um diese wieder reinzukriegen.
hatte gestern auch ganau das gleiche problem. habs evtl. etwas pfuschig gelöst: nimm für jede ziffer eine eigene variable: stunden 1er, stunden 10er, minuten 1er, minuten 10er, usw... wie gesagt vlt nicht die schönste lösung aber funzt! gruß grassh0pper
rené s. schrieb: > hatte gestern auch ganau das gleiche problem. > habs evtl. etwas pfuschig gelöst: > nimm für jede ziffer eine eigene variable: > stunden 1er, stunden 10er, minuten 1er, minuten 10er, usw... > wie gesagt vlt nicht die schönste lösung aber funzt! keine so gute Lösung. Du verringerst zwar den Aufwand bei der Ausgabe, dafür hast du aber mehr Aufwand beim Weiterzählen der Uhrzeit. Wenn dann zb noch Weckzeiten ins Spiel kommen, schlägt das ganze dann ins Gegenteil um. Für ein bischen einfachere Programmierung in der Ausgabe treibst du eine Menge Mehraufwand in der internen Behandlung von Zeiten.
Man kann auch mit strlen abfragen ob eine oder zwei Stellen vorhanden sind und die 0 dann wieder einfügen.
Hubert G. schrieb: > Man kann auch mit strlen abfragen ob eine oder zwei Stellen vorhanden > sind und die 0 dann wieder einfügen. Leider Nein, denn die führende '0' müßte davor eingefügt werden. Wer weiß was dort steht und somit überschreibt. Die Methode von Klaus Wachtler funktioniert deshalb, weil er einen Puffer = array of char vorgibt. Die sicherste, insbesondere bei falschen Werten, ist sprintf.
Das schöne Wetter hat mich davon abgehalten, das zu testen. Ich werd das aber schon noch nachholen. Karl Heinz Buchegger schrieb: > Wenn du sowieso eine hauseigene itoa Lösung hast, ist es am besten sich > mit dem Systemprogrammierer kurzzuschliessen und ihn um eine > Spezialversion zu bitten. Da hab ich mich wohl mißverständlich ausgedrückt. Ich meinte mit 'hauseigen' die, die avr-gcc mitbringt.
>sprintf()...
Boahh. Dann ist der halbe Speicher weg und man kann sich gleich den
Strick suchen...
Multi Oschi schrieb: >>sprintf()... > > Boahh. Dann ist der halbe Speicher weg und man kann sich gleich den > Strick suchen... Übertreib nicht. Bei einem Mega32 hat er genug Speicher, dass er sich sprintf für den Anfang leisten kann.
Da bei sprintf der Compiler Probleme bereitete, hab ich jetzt einfach den Vorschlag von Klaus Wachtler übernommen. Für meine Anwendung völlig ausreichend und funktioniert auch wunderbar. Vielen Dank für die Hilfe nochmal!
MarioG schrieb: > Da bei sprintf der Compiler Probleme bereitete Ich bezweifle daß der Compiler das Problem ist. Bei uns heisst es: "Das Problem sitzt meistens vor der Tastatur" Und zu 99% stimmt das, sogar dort wo mit Software Geld verdient wird :-)
Wahrscheinlich fehlt einfach nur der richtige Include für sprintf #include <stdio.h>
Hallo, ach wie schade. Ich hatte gerade Temp = stunden / 10; durch Temp = ( int (stunden) * 26) >> 8 ; ersetzt, was auch nur bis knapp über 60 funktioniert und ohne Divsion auskommt.
Karl Heinz Buchegger schrieb: > Wahrscheinlich fehlt einfach nur der richtige Include für sprintf > > #include <stdio.h> Das hatte ich schon beachtet. Udo Schmitt schrieb: > Ich bezweifle daß der Compiler das Problem ist. > Bei uns heisst es: "Das Problem sitzt meistens vor der Tastatur" > Und zu 99% stimmt das, sogar dort wo mit Software Geld verdient wird :-) Das Problem sitzt insofern vor der Tastatur, als daß ich nicht bereit war, ewig Zeit zu investieren, um den Fehler zu suchen und zu beheben. Ich sollte vielleicht erwähnen, daß ich nicht unter Windows mit AVRStudio arbeite, sondern unter Linux mit Codeblocks. Das Problem scheint in der in meinem ubuntu release (10.10 bzw maverick merkaat) verwendeten avr-libc zu liegen. Die Fehlermeldung lautete wie folgt: "/usr/lib/avr/lib/libc.a(vfprintf_std.o): In function `vfprintf': /build/buildd/avr-libc-1.6.8/avr/lib/avr2/../../../libc/stdio/vfprintf.c :338: undefined reference to `__mulhi3' /build/buildd/avr-libc-1.6.8/avr/lib/avr2/../../../libc/stdio/vfprintf.c :341: undefined reference to `__mulhi3'" An einer Problemlösung wäre ich natürlich schon interessiert! Horst Hahn schrieb: > Hallo, > > ach wie schade. > Ich hatte gerade > Temp = stunden / 10; > durch > Temp = ( int (stunden) * 26) >> 8 ; > ersetzt, was auch nur bis knapp über 60 funktioniert und ohne Divsion > auskommt. Temp = ( int (stunden) * 26) / 256 ; würde das der Compiler nicht genauso interpretieren? Wäre auf jeden fall einfacher zu lesen ;)
char puffer[4]; lcd_clear(); itoa((int) stunden+100, puffer, 10); lcd_string(&puffer[1]); lcd_string(" : "); itoa((int) minuten+100, puffer, 10); lcd_string(&puffer[1]); lcd_string(" : "); itoa((int) sekunden+100, puffer, 10); lcd_string(&puffer[1]);
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.