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??
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
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.
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...
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.
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.
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??
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.
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).
Matthias schrieb:> in> OCR2 = 234374;> geändert und es kommt kein Fehler mehr?!>> Müsste denn nicht ein Fehler wegen der Register Größe kommen??
Nein, man darf ja durchaus Integer unterschiedlicher Größe einander
zuweisen. Da das aber gerne mal (wie jetzt bei dir) zu ungewollten
Ergebnissen führt, kommt da eine Warnung.
Oliver
Okay vielen dank für die antworten...
Ich werd dann einfach in der timer overflow ISR eine variable
inkrementiern lassen und nach 60s die werte auslesen.
Eine eigene Frage?
Dieser Thread ist über 15 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.