Timer und Idle-Mode

Gast #2262889
Lesenswert?

Hallo,

also ich verwende einen ATmega8 mit 4MHz und will das er jede Minute 
aufwacht, die Temperatur misst, am LCD ausgibt und wieder in den Idle 
Mode geht. Ich wollte den Idle Mode verwenden, weil bei diesem die Timer 
noch verfügbar sind und der µC auch durch den Timer (Interrupt) wieder 
aufwacht.

So jetzt weiß ich aber nicht wie ich das am besten machen soll, das der 
Timer nur einen (wegen Idle Mode) Interrupt erzeugt (alle 60s).

Mit dem Prescaler (1024) komm ich auf 3906,25 Takte pro Sekunde und 
234375 Takte bei 60s. Das dieser Wert zu groß für ein 8 / 16 Bit 
Register ist ist mir schon klar, nur hab ich im "AVR-GCC-Tutorial/Die 
Timer und Zähler des AVR" das gelesen:
"Im CTC Modus des Timers ist es möglich, anstelle der durch die Hardware 
bedingten Obergrenze des Timers, eine andere Zahl zu benutzen, an der 
der Timer einen Interrupt auslöst".

Dann wollte ich gleich den Timer2 verwenden, aber es erscheint immer 
eine Fehlermeldung beim Simulieren:
stray '\226' in program
expected ';' before numeric constant


Hier der Timer Code dazu:

TCCR2 |= (1<<WGM21);                         // Timer2 --> CTC Modus
TCCR2 |= (1<<CS20) | (1<< CS21) | (1<<CS22);       // Prescaler 1024
OCR2 = 234375–1;            // Timer vorladen (60s)
TIMSK |= (1<< OCIE2);      // Compare Interrupt erlauben


also denke ich das der Wert für das Register doch zu groß ist??
oder kann ich eine Variable hochzählen lassen, ohne Interrupt??
Gast #2262908
Lesenswert?

Matthias schrieb:
> "Im CTC Modus des Timers ist es möglich, anstelle der durch die Hardware
> bedingten Obergrenze des Timers, eine andere Zahl zu benutzen, an der
> der Timer einen Interrupt auslöst".

Dadurch werden die Register aber auch nicht größer. Bei 0xff bzw. 0xffff 
ist Schluß, mehr geht nicht.

Die einzige Lösung ist, einen Softwarezähler zu nutzen. Da wird der AVR 
halt dann innerhalb der Minute ein paar mal aufwachen und addieren 
müssen, aber das macht im Vergleich zu der langen LCD-Ausgabe (fast) 
nichts aus.

Matthias schrieb:
> stray '\226' in program
> expected ';' before numeric constant

Die Fehlermeldung hat aber nichts mit der zu großen Konstante zu tun.
> OCR2 = 234375–1;            // Timer vorladen (60s)
Das - Zeichen ist komisch, das gefällt dem Compiler nicht.

Oliver
#2262914
Lesenswert?

Matthias schrieb:
> Ich wollte den Idle Mode verwenden, weil bei diesem die Timer
> noch verfügbar sind

Sind sie nicht. Timer2 ist noch verfügbar. Allerdings wird die CPU-Clock 
abgeschaltet. Sodaß der Timer eine eigene Taktquelle braucht.
Dazu benutzt man einen Uhrenquarz.

Matthias schrieb:
> also denke ich das der Wert für das Register doch zu groß ist??

Das ist ein 8-Bit Register. Das geht von 0 - 255.

Matthias schrieb:
> oder kann ich eine Variable hochzählen lassen, ohne Interrupt??

Nein.

Du kannst aber auch einen Atmega 48/88/168/328 nehmen und den 
Watchdogtimer zum regelmässigen Aufwecken benutzen.

mfg.
Gast #2262996
Lesenswert?

ich benutze noch einen externen Quarz (4MHz). Dieser müsste doch im Idle 
Mode noch funktionieren??


Okay ich hab jetz mal die Zeile:

OCR2 = 234375–1;

in

OCR2 = 234374;

geändert und es kommt kein Fehler mehr?!
Müsste denn nicht ein Fehler wegen der Register Größe kommen??

Naja gut dann werd ichs wohl so programmieren müssen, dass er ein paar 
mal mit Timer2 aufwachen muss...
#2263011
Lesenswert?

Matthias schrieb:

> ich benutze noch einen externen Quarz (4MHz). Dieser müsste doch im Idle
> Mode noch funktionieren??

Aber nicht in den echten Powerdown/save-Modi, die den Hauptoszillator 
abschalten. Für einen zweiten Quarz hat der Mega8 keine Pins. Dazu 
müsstest du auf internen Hauptoszillator gehen und für den Timer2 einen 
32KHz Quarz anschliessen.

Wenn es darum geht, wirklich Strom zu sparen, dann geht es mit dem 
pinkompatiblen ATmega88 einfacher: Watchdog-Interrupt alle 8 Sekunden 
freigeben (der ATmega8 kann nur Watchdog-Reset). Kannst dann voll in den 
Powerdown-Modus gehen.
#2263028
Lesenswert?

Matthias schrieb:
> OCR2 = 234374;

Auch wenn es keine Fehlermeldung gibt, passt es da nicht rein.
Die untersten 8 Bit werden da reingeschrieben, der Rest wird 
abgeschnitten.

Matthias schrieb:
> Dieser müsste doch im Idle Mode noch funktionieren??

Nein. Der wird abgeschaltet.

Siehe den Post von A. K. (prx). Der hat es genau auf den Punkt gebracht.

mfg.
#2263034
Lesenswert?

Matthias schrieb:

> Im Datenblatt steht aber das beim Idle Mode die "Main Clock
> Source Enabled" und die "Timer Osc. Enabled (If AS2 bit in ASSR is
> set.)" ist, also auch das Quarz??

Im noch relativ viel Strom fressenden "Idle" Mode, der ausschliesslich 
CPU und Flash abschaltet, kannst du jeden Timer verwenden. Das AS2 Bit 
darf auf dem Mega8 bei einem Hauptoszillator mit Quarz nicht aktiviert 
werden, weil die Pins schon vom Hauptsozillator verbraten sind.
#2263043
Lesenswert?

Apropos Watchdog: Wenn es nur darum geht, einmal die Minute einen 
Messwert anzuzeigen, dann geht das natürlich auch mit dem Mega8. Indem 
der Watchdog-Reset ihn frisch starten lässt. Müsst dann nur dafür 
sorgen, dass die Variable, die aus den 8 Sekunden die Minuten macht, vom 
Watchdog-Reset verschont wird und nur bei Powerup/Brownout-Reset 
initialisiert wird (MCUSR abfragen).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren