Beim Umstricken eines Atmega8 Codes auf einem Atmega88 bin ich über
folgende Hürde gestolpert:
Der Atmega88 kann im async. Betrieb (32Khz Uhrenquarz) aus dem Powersave
über eine Timer2-ISR geweckt werden (wie beim Atmega8).
Der Atmega88 darf aber erst wieder in den Powersave versetzt werden,
wenn TOSC1 seinen nächsten Taktimpuls bekommt (d.h. 30µs beim
Uhrenquarz).
Da meine ISR nur 10µs dauert wird diese ca. 3x direkt hintereinander
aufgerufen, bis wieder Ruhe ist, d.h. an TOSC1 eine neue positive Flanke
anliegt.
Im Atmega88 Manual unter 17.9 wird als Lösung des Dilemmas empfohlen,
einfach ein unbenutztes Timer2 Register zu schreiben und das
entsprechende Update Busy Flag in ASSR abzuwarten, bis TOSC1
weitergezählt hat. Danach kann der AVR in den Powersave versetzt werden.
Das funktioniert auch Problemlos:
1
_isr_t2ovf:
2
push r16
3
in r16,sreg
4
push r16
5
6
OUT OCR2A, R24 ;set OCR2AUB with Timer 2 register dummy write
7
8
; ... ISR Code (<10µs)
9
10
_t2ovf_end:
11
LDS R16, ASSR
12
SBRC R16, OCR2AUB ;wait until OCR2AUB returns to zero
13
RJMP _t2ovf_end
14
15
pop r16 ;get content of SREG
16
out sreg,r16 ;restore sreg
17
pop r16
18
RETI
Blöderweise wird ein Timer2-Zähler erst nach 2(!!) positiven Flanken am
TOSC1 aktualisiert.
D.h. das Warten auf OCR2AUB verlängert die ISR von 10µs auf
2/32768=61µs. (Faktor 6)
Da das System über Batterie betrieben wird ist das unakzeptabel.
Mir fallen nur noch 2 Lösungen ein:
- die ISR über NOP auf >30,5µs zu strecken
- den AVR herunterzutakten, so dass die ISR länger als 31µs dauert
Heruntertakten wäre die spromsparendste Variante.
Hat jemand noch eine Idee?
Wie gesagt, beim Atmega8 gibt es dieses Problem nicht.
@ Thomas (Gast)
>entsprechende Update Busy Flag in ASSR abzuwarten, bis TOSC1>weitergezählt hat. Danach kann der AVR in den Powersave versetzt werden.
Genau so macht man das.
>Das funktioniert auch Problemlos:
Wo ist das Problem?
>D.h. das Warten auf OCR2AUB verlängert die ISR von 10µs auf>2/32768=61µs. (Faktor 6)>Da das System über Batterie betrieben wird ist das unakzeptabel.
Käse. Rechne mal den "unglaublichen" Stromverbauch aus. Siehe [[Sleep
Mode]].
>Mir fallen nur noch 2 Lösungen ein:>- die ISR über NOP auf >30,5µs zu strecken
Kann man machen.
>- den AVR herunterzutakten, so dass die ISR länger als 31µs dauert
Geht auch.
>Heruntertakten wäre die spromsparendste Variante.
Ja.
>Wie gesagt, beim Atmega8 gibt es dieses Problem nicht.
Doch, der muss auch mindestens einen Timertakt warten, sonst wird er nie
mehr geweckt.
MFG
Falk
Thomas wrote:
> Da das System über Batterie betrieben wird ist das unakzeptabel.
Wie kommst Du darauf?
Hast Du denn nachgemessen, um wieviel sich die mittlere Stromaufnahme
erhöht?
Und übersteigt sie auch wirklich den von Dir kalkulierten Wert für die
geplante Betriebsdauer?
Man muß sich nicht über den Fliegenschiß an der Wand ärgern, wenn man
ihn nichtmal sieht.
> - den AVR herunterzutakten, so dass die ISR länger als 31µs dauert
Das Runtertakten dürfte die bessere Lösung sein.
Ich hab mal mit nem ATtiny45 Messungen gemacht und den Eindruck
gewonnen, daß die Stromaufnahme von der Anzahl ausgeführter Befehle
abhängt.
> Wie gesagt, beim Atmega8 gibt es dieses Problem nicht.
Dafür verbraucht er auch deutlich mehr Strom im asynchronen Modus.
Peter
>Hast Du denn nachgemessen, um wieviel sich die mittlere Stromaufnahme
erhöht?
Klar, habe ich das nachgerechnet. Die ISR wird mit 128Hz aufgerufen:
Atmega88 @ 8Mhz und 5V
Active Supply Current: 5mA
Power-Save Supply Current: 8µA
ISR mit 128Hz Takt und 10µs Dauer: Ieff = 14µA (100%)
ISR mit 128Hz Takt und 30µs Dauer: Ieff = 27µA (192%) ISR verlängert auf
30µs
alternative Variante Heruntertakten:
Atmega88 @ 1Mhz und 5V
Active Supply Current: 0,9mA
Power-Save Supply Current: 8µA
ISR mit 128Hz Takt und 8*10=80µs Dauer: Ieff = 17µA (121%)
Ich weiß, dass die Aktive-Phase etwas länger ist, als die reine ISR:
WakeUptime: 6 Cycl
Interruptvektor: 6 Cyl
Reti: 1 Cycl
Sleep: 1 Cyl
14 Cycl das sind bei 8Mhz noch 2µs extra.
Ich messe zum Schluß den genauen Stromverbrauch über eine
Kondensatorentladekurve.
Entgegen der klass. Stromsparregel "Hohe Taktfreqenz und viel Schlafen"
werde ich werde mein Design auf 1Mhz herunterfahren müssen.
@Thomas (Gast)
>Entgegen der klass. Stromsparregel "Hohe Taktfreqenz und viel Schlafen">werde ich werde mein Design auf 1Mhz herunterfahren müssen.
Die Regel gilt doch weiterhin. Ausserdem sollte die Umschaltung des
Prescalers problemlos das ermöglichen. Am Anfang der ISR, Prescaler auf
1 MHz, am Ende wieder auf 8 MHz.
MFg
Falk
Falk Brunner wrote:
>Am Anfang der ISR, Prescaler auf>1 MHz, am Ende wieder auf 8 MHz.
Danke, sehr guter Hinweis
>Doch, der Atmega8 muss auch mindestens einen Timertakt warten,>sonst wird er nie mehr geweckt.
Du hast Recht, ich habe es gerade im Datenblatt gefunden.
Wer lesen kann ist klar im Vorteil :-)
Falk Brunner wrote:
>>Doch, der Atmega8 muss auch mindestens einen Timertakt warten,>>sonst wird er nie mehr geweckt.>Du hast Recht, ich habe es gerade im Datenblatt gefunden.
Ich habe den Atmega88 aus dem Board herausgenommen und einem Atmega8 und
einem Atmega8L nachgemessen (Oszi):
Beide Atmega8 wachen wieder auf, auch wenn sie schon nach 10µs schlafen
gelegt werden (TCCR2 Prescaler 1).
Beim Atmega8 stimmt Datenblatt und Realität nicht überein.
Wie gesagt es ist der gleiche Code und Boarddesign (Atmega8 / Atmega88).
Verrückt...
Vielen Dank für Eure Hilfe.
Insbesonders an Dich, Peter Dannegger, denn es ist seit Jahren Dein
Bulletproof Debounce Code, der mich dazu bewegt, alle RTCs von 1Hz auf
128Hz hochzutreiben. Der nächste Prescaler kommt auf 16Hz, das macht die
Tasten recht träge.
Thomas wrote:
> Insbesonders an Dich, Peter Dannegger, denn es ist seit Jahren Dein> Bulletproof Debounce Code, der mich dazu bewegt, alle RTCs von 1Hz auf> 128Hz hochzutreiben.
Warum das denn?
Du kannst doch mit dem Pin-Change Interrupt aufwachen und dann mit nem
schnelleren Timer die Tasten entprellen.
Peter