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?
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.
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.
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 :-)
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 ;)