Guten Abend,
ich baue momentan eine kleine Binäruhr mit einem Atmega8. Die Idee war
eine Einfache Binäruhr (Minuten 0-59, Stunde 0-11,, 2LEDs für Sekunden)
und diese über 2 Taster( Stunde+1, Minute+1) einzustellen. Die Binäruhr
fängt auch schon an zu zählen das Problem liegt daran dass ich die
Uhrzeit nicht Einstellen kann. Die Taster sind PD5 und PD2 mit dem µC
verbunden, PullDown Wiederstände gehen von dort auf Ground.
Hardwaremäßig funktioniert alles (nachgemessen mit Multimeter etc.). Es
kann gut sein dass die Uhr nicht genau Zählt, dies ist bekannt und wird
später behoben.(Externer Quarz etc.)
Lg Sebastian
Sebastian schrieb:> Die Taster sind PD5 und PD2 mit dem µC> verbunden, PullDown Wiederstände gehen von dort auf Ground.
Das solltest du mit einem Schaltplan verdeutlichen da es
sonst keiner versteht. Oder viele missverstehen und raten.
S. Landolt schrieb:> Fehlt da nicht 'volatile' für sekunden minuten stunden?
Ich hab mal volatile davor geschrieben. Scheint als wäre es hier nötig,
doch warum eigentlich? Es sollte doch kein Problem sein auf eine Globale
Variable zuzugreifen? Oder irre ich mich hier?
1) was macht die Routine timer() ? Ist das nicht redundant zur ISR?
2) fehlendes volatile bei stunden, minuten und sekunden wurde ja schon
angemerkt.
3) die Taster sind nicht entprellt.
4) wenn es dann mal funktioniert (mit volatile), wird ein Tasterdruck
die Uhr scheinbar "zufällig" verstellen, weil in jedem
Schleifendurchlauf der Portpin gesetzt ist, und diese Schleife wird
zigtausendmal jede Sekunde durchlaufen.
Sebastian schrieb:> Scheint als wäre es hier nötig, doch warum eigentlich?
Das ist immer nötig, wenn Du Variablen zwischen Applikation und
Interrupt teilst, weil der Kontrollfluß nicht linear ist.
an Sebastian:
Das kann ich leider nicht beantworten, kann kein C; ich lese nur
regelmäßig mit, und das fehlende 'volatile' im Zusammenhang mit ISRs
scheint ein häufiger Fehler zu sein.
an Nop:
die Punkte 3 und 4 werden so halbwegs durch das
_delay_ms(100);
in der main umgangen.
Nop schrieb:> weil in jedem> Schleifendurchlauf der Portpin gesetzt ist, und diese Schleife wird> zigtausendmal jede Sekunde durchlaufen.
Nö, nur ca zehnmal pro Sekunde, weil er ein _delay_ms(100)
in der Schleife hat.
S. Landolt schrieb:> die Punkte 3 und 4 werden so halbwegs durch das> _delay_ms(100);> in der main umgangen.
Stimmt, zumindest das Prellen. Aber es wird schwerlich möglich sein, die
Stunden und Minuten um genau eins vorzustellen. Das müßte man dann so
machen, daß man den Port abfragt und nur dann eins weiterstellt, falls
der jeweilige Portzustand im vorigen Durchlauf null war (speichert man
in einer Statusvariable).
Der genaue Grund, wieso volatile nötig ist, ist die Optimierung des
C-Compilers. Wenn der Kontrollfluß nicht zusammenhängend ist (wie bei
Applikation/Interrupt), optimiert er da u.U. ungewollt Zugriffe weg.
Typisches Symptom: mit -O0 (ohne Optimierung) geht es, mit Optimierung
(egal ob auf Zeit oder Codegröße) geht es nicht mehr.
Nop schrieb:> 1) was macht die Routine timer() ? Ist das nicht redundant zur> ISR?
Ja, wird noch entfernt
> 2) fehlendes volatile bei stunden, minuten und sekunden wurde ja schon> angemerkt.>> 3) die Taster sind nicht entprellt.
Die Taster entprelle ich mal wenn ich zeit habe. Bis es so weit ist muss
ich ohne klarkommen. durch das delay fällt es nicht so sehr auf.
> 4) wenn es dann mal funktioniert (mit volatile), wird ein Tasterdruck> die Uhr scheinbar "zufällig" verstellen, weil in jedem> Schleifendurchlauf der Portpin gesetzt ist, und diese Schleife wird> zigtausendmal jede Sekunde durchlaufen.
Wird durch das _delay_ms(100); begrenzt. Es ist bewusst so gemacht dass
ein schnelles verstellen möglich ist.
Mit Interrupts habe ich mich noch nicht so viel auseinandergesetzt daher
warscheinlich das fehlende volatile.
Danke an alle. Hat mir sehr geholfen. Noch einen schönen Abend :)
Sebastian schrieb:> Die Taster entprelle ich mal wenn ich zeit habe. Bis es so weit ist muss> ich ohne klarkommen. durch das delay fällt es nicht so sehr auf.
Dauert doch nicht lange?