Forum: Mikrocontroller und Digitale Elektronik Uhr mit quarz, Atmega48 und AVRC


von Jonathan S. (x0136)


Angehängte Dateien:

Lesenswert?

Ich habe mir ne Uhr gebastelt, die die Stunden und Minuten binär mit 
einzelnen LEDs anzeigt.
Bei den ersten Versuchen sah es auch ganz gut aus, die Zeit wurde 
angezeigt, hat auch nach 1 oder 2 Stunden noch gestimmt und die 
restlichen Funktionen haben auch funktioniert. Nach einem Tag Betrieb 
ist das Teil dann irgendwie hängen geblieben, hat nur noch die gleiche 
Zeit angezeigt und wollte sein Display auch nicht mehr ausschalten.
Ich vermute mal der Fehler liegt im Code.
Leider kann ich keinen Fehler finden.
Hoffe irgendjemand kann mir weiterhelfen.

Zur Funktionsweise:
Die Uhr hat zwei Taster. Der eine schaltet das Display an und wechselt 
bei erneutem Druck in den Modus zum Einstellen der Minuten bzw. Stunden. 
Wird der zweite Taster gedrückt, werden, falls man sich gerade im 
Einstellmodus befindet je nachdem entweder die Minuten oder Stunden um 1 
erhöht.
Ca. 5 Sekunden nach dem letzten Tasterdruck schalten sich die LEDs aus 
und der µC geht in den Sleepmodus.

von m.n. (Gast)


Lesenswert?

Laß uns mal mit den Tastendrücken anfangen. Das Aufwachen und Entprellen 
sind etwas undurchsichtig programmiert.
Eine schlichte Entprellung käme ganz ohne Timer aus, braucht aber an 
INT0 und INT1 jeweils ein RC-Glied: typ. 10 kOhm und 470 nF bei 
aktiviertem internen Pullup. Der Nachteil bei dieser Variante ist das 
mögliche unvollständige Entladen des Cs. Besser ist es, den Kondensator 
immer gezielt voll zu ent- bzw. aufzuladen, wie es nachfolgend gezeigt 
wird.

Wenn Du stattdessen den PCINT nutzen würdest, hätte ich ein fertiges 
Programm dafür: Beitrag "Re: EIN-AUS mit Taster per Interrupt, ATtiny25 o.ä."
Hier weckt jeder Tastendruck den µC auf und liefert beim Drücken den 
Tastencode '1' oder '2', der in main() direkt nach dem Aufwecken 
ausgewertet werden kann.

Soweit für den Anfang.

von Jonathan S. (x0136)


Lesenswert?

Leider ist auf der Platine kein Platz für weitere elektronische 
Bauteile, weswegen das Entprellen per Software gelöst werden muss.

Zu meiner Entprellmethode: wird ein Taster gedrückt, wird ein Timer 
gestartet. Der erreicht dann den compare-Wert und wirft einen Interrupt 
bei dem geschaut wird, ob der Taster noch gedrückt ist und demnach dann 
die entsprechende Funktion ausführt. Das hat bis jetzt auch ganz gut 
funktioniert ;)

von Peter D. (peda)


Lesenswert?

Jonathan S. schrieb:
> Ca. 5 Sekunden nach dem letzten Tasterdruck schalten sich die LEDs aus
> und der µC geht in den Sleepmodus.

Sleep hat einige Fallstricke, wenn kein Batteriebetrieb gefordert ist, 
laß ihn weg.
Ansonsten erstmal die Funktion aufbauen und testen. Und danach erst 
Sleep hinzufügen und testen.

von Jonathan S. (x0136)


Lesenswert?

Peter D. schrieb:
> wenn kein Batteriebetrieb gefordert ist
Die Uhr muss mit Batterie laufen, sonst hätte ich auch keinen Sleep 
reingepackt.
Kann es sein, dass ich den falsch verwendet habe? Das ist mein erstes 
AVRC Projekt, deswegen habe ich da sehr wenig Ahnung.

von Bastler (Gast)


Lesenswert?

Peter Vorschlag soll bewirken, daß die Uhr selbst fehlerfrei läuft.
Und danach wird Sleep eingebaut. So macht man das beim Software 
debuggen. Sonst weiß man nur "geht nicht".
 Oder mit dem alten Donald Knuth: erst muß es funktionieren, dann wird 
optimiert (hier Strom gespart).
 Es gibt natürlich Leute, die haben Standarddinge schon so oft gemacht, 
daß sie es einfach runterschreiben können. Aber die fragen danach dann 
auch nicht hier.

von Jonathan S. (x0136)


Lesenswert?

Ich hab die Uhr jetzt zwei Wochen ohne Sleep getestet.
Sie hat mittlerweile zwar 1-2 Minuten Verspätung, aber ansonsten läuft 
sie einwandfrei.
Es muss also doch am Sleep liegen.

von Jonathan S. (x0136)


Lesenswert?

Niemand eine Idee?
ohne Sleep funktioniert es einwandfrei.
Mit Sleep treten einige komische Fehler auf.
Mit Sleep sieht die endlosschleife in meiner main so aus:
1
while(1){
2
    if(shouldSleep==1){
3
    EIMSK |= (1<<INT0);  //externen INT0-Interrupt freigeben
4
    OCR2B = 0;    //Dummy-Zugriff
5
    while((ASSR & (1<<OCR2BUB)));  //warte auf Ende des Zugriffs
6
    
7
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
8
    sleep_enable();
9
    sleep_cpu();
10
    
11
    sleep_disable();
12
    }
13
  }
14
}

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
Noch kein Account? Hier anmelden.