Hallo,
Ich habe ein funktionierendes Programm welches ich um eine zusätzliche
Funktionalität erweitern möchte.
Ich möchte alle 8 Sekunden (über einen Watchdog Interrupt gesteuert) die
Spannung der angeschlossenen Akkus überprüfen. Sollte die Spannung unter
2V (zwei NIMH in Reihe) liegen solle sich der Controller, ein
Atmega88pa, schlafen legen. Alle 8 Sekunden soll er wieder aufwachen,
die Spannung überprüfen und solange diese nicht über 2,4V liegt weiter
schlafen.
Wie gehe ich das am besten an?
Also hätte jetzt an sowas gedacht:
.include "m88padef.inc"
.org 0x006
rjmp Stromsparen
rcall init
main:
.
.
.
rjmp main
init:
ldi r16,(1<<wdce)
sts WDTCSR,r16
ldi r16,(1<<WDIE)|(1<<WDP3)|(1<<WDP0) ;Watchdog mit 8s in Interrupt Mode
ret
Stromsparen:
push r16 ;r16 und sreg sichern
in r16,sreg
push r16
rcall Adceinlesen ;liefert Batteriespannung
cpi r16, 103
brlo schlafen
pop r16
out sreg, r16
pop r16
reti
schlafen:
ldi r16,(1<<SM2)|(1<<SM1)|(1<<SE)
pop r16
out sreg, r16
pop r16
sleep
[/avrasm]
@Jobst: schau doch lieber selber nochmal nach. Bei den etwas neueren
AVRs kann der Watchdog beides.
Jobst M. schrieb:> Dann schau Dir nochmal die Schafmodi und deren Weckmöglichkeiten im> Datenblatt an. Der WDT resetet Deinen Prozessor.
Kommt drauf an. Bei manchen (neueren?) AVRs kann man den Watchdog auch
so konfigurieren, daß er beim ersten Ablaufen nur einen Interrupt
generiert und erst beim zweiten einen Reset, oder auch daß er nur den
Interrupt generiert.
Tatsächlich habe ich bei meiner erste blinkende LED mit einem AVR das
Blinken über den Watchdog-Timer der Tiny13 gesteuert, statt über einen
normalen Timer, weil ich halt beim Lesen des Datenblatts erst dort
vorbeigekommen bin ;-)
Okay. Stimmt.
"In Interrupt mode, the WDT gives an interrupt when the timer expires.
This interrupt can be used to wake the device from sleep-modes, and also
as a general system timer."
Der Interupt-Mode ist mir neu.
Dann ist er aber quasi zum Timer degradiert.
Zum Programm: Bei zu geringer Batteriespannung wird der Prozessor
schlafen gelegt, bevor der WDT initialisiert wird.
Gruß
Jobst
Nicht degradiert, erweitert ;) Er kann das ja noch zusätlich. Das feine
darin ist, dass man den Controller aus jedem schlaf wecken kann.
Zum Programm: eigentlich dürfte nichts passieren, kein sei weit und
breit. Das gehört noch ans Ende von init.
Ich brauche leider doch nochmal ein bisschen Hilfe.
Der Stand ist: Programm läuft, Interrupt wird aufgerufen ADC Wert
eingelesen und dementsprechend weitergemacht oder geschlafen. Das
Problem ist: Ist der Controller einmal eingeschlafen wacht er nicht mehr
auf.
Hier das entscheidende Codestück:
1
schlafen:
2
ldi r16,0b00001111
3
out SMCR,r16 ;sleep einschalten, extended Standby
4
pop r16 ;sreg und r16 wieder herstellen
5
out sreg, r16
6
pop r16
7
sleep ;schlafen
8
reti
ich bin mir nicht wirklich sicher, ob ich den Controller in einer ISR
schlafen schicken kann. Und ob das so funktioniert wie ich es
geschrieben habe.
Danke für eure Hilfe.
Hi
>ich bin mir nicht wirklich sicher, ob ich den Controller in einer ISR>schlafen schicken kann. Und ob das so funktioniert wie ich es>geschrieben habe.
Da das ganze vor dem RETI passiert dürften weitere Interrupts gesperrt
sein.
MfG Sspess
Jobst M. schrieb:> Der Interupt-Mode ist mir neu.> Dann ist er aber quasi zum Timer degradiert.
Die andere Perspektive ist: Toll, ein Timer mit zusätzlicher Watch dog -
Funktionalität ;-)
Auf den kleinen MSP430 gibt es nur einen normalen Timer. Dessen
Interrupts helfen allerdings nichts im "low power mode 3", da dort
dessen Clock aus ist. Dort bleibt gar nichts anderes übrig als den Watch
dog - Timer zu nehmen, dessen Clock auch in diesem Modus noch an ist.