Hallo!
Kann mir jemand helfen...
ich komm bei der Programmierung einer einfachen Uhr für einen AVR (mit
GCC)einfach nicht weiter. Das LCD (47780 - 2*16) zeigt Stunden und
Minuten nur einstellig und zählt die Sekunden in Zehnerschritten bis
1000 hoch. Keine Ahnung warum. Außerdem läuft das ganze zu schnell.
Danke im Vorraus,
Felix
Hier der Code:
@ Felix G. (Gast)
>Minuten nur einstellig und zählt die Sekunden in Zehnerschritten bis>1000 hoch. Keine Ahnung warum. Außerdem läuft das ganze zu schnell.>Danke im Vorraus,> TCCR1A = (1<<WGM01); // CTC
Falsch! Falsches Bit, falsche Register.
Eher so.
TCCR1B |= (1<<WGM12) | (1<<CS10); // Prescaler 1, CTC Mode
> if (milli == 1000) //Sekunden inkrementieren>{milli = 0;> sekunden ++;
OK
>_delay_ms(10);
Was soll der Unsinn?
MfG
Falk
Hallo Felix,
ich vermute einen Buffer-Overflow bei den Sekunden, weil deine
char-array nur 2 Bytes lang ist. Da ist dann kein Platz mehr für den
String-Terminator.
Wenn die Zahl unter 10 ist, gibt itoa halt nur ein einstelliges Ergebnis
im String. Eine Alternative wäre sprintf.
Gruß, DetlevT
Dein String ist gar nicht so lang, dass er eine zweistellige Zahl
enthalten kann, denn die abschließende '\0' gehört zum String. Du
kriegst also Überläufe. Zudem sorgst Du nicht für die Darstellung der
führenden Null, der obige String wird in den ersten 10 Minuten
tatsächlich nur einstellig ausgegeben. Das gilt für alle Deine itoa()s.
Die Sekunden zählen vermutlich nur scheinbar in 1000er Schritten hoch,
Was Du als Nullen hinten siehst, dürfte nicht jedesmal geschrieben
werden, sondern Folge früherer Ausgaben sein, z.B. zweistellige
Ausgaben, die durch Überlauf der Strings sogar möglicherweise mit noch
viel mehr Stellen ausgegeben wurden.
Weiter habe ich nicht geschaut.
@ Felix G. (Gast)
>Minuten nur einstellig und zählt die Sekunden in Zehnerschritten bis>1000 hoch. Keine Ahnung warum. Außerdem läuft das ganze zu schnell.>Danke im Vorraus,> TCCR1A = (1<<WGM01); // CTC
Falsch! Falsches Bit, falsche Register.
Eher so.
TCCR1B |= (1<<WGM12) | (1<<CS10); // Prescaler 1, CTC Mode
> if (milli == 1000) //Sekunden inkrementieren>{milli = 0;> sekunden ++;
OK
>_delay_ms(10);
Was soll der Unsinn?
>char sekundenascii [2]; //int to ascii>itoa (sekunden, sekundenascii, 10);
Wird bissel knapp mit den Sekunden. Denn die brauchen DREI Bytes, zwei
für die Zahl, eins für das Abschlusszeichen NULL.
Ausserdem definiert man Variablen nicht mitten im Quelltext. Das gehört
an den Anfang.
Ausserdem hast du ggf. noch ein Problem, nämlich der nichtatomare
Vergleich und Zugriff auf milli, siehe Interrupt. Das macht man
anders, mit einem Flag. Siehe unten.
Danke!!! Wieder was gelernt.
Hätt ich nur noch zwei kleine Fragen:
1. Was hat das mit den zwei Registern A & B beim Timer 1 auf sich? (Is
das ein 32 bit Timer oder sowas?
2. Wäre eine voranstehende Null bei Stunden/Minuten mit wenig
Speicheraufwand möglich (sprintf is ja eher speicherintensiv)