Forum: Mikrocontroller und Digitale Elektronik Watchdog und sleep mode


von Christoph -. (con-f-use)


Lesenswert?

Hallo,

ich habe ein kleines Projekt auf einem AtTiny45. Ich möchte ein paar 
Daten auslesen, den Tiny in den power down schicken und nach vier 
Sekunden über den watchdog wieder aufwecken damit das Spielchen von 
vorne losgehen kann. Ich bin mir allerdings nicht sicher, ob ich alles 
richtig gemacht habe.

Ich wäre dankbar, wenn sich jemand meinen Code anschauen könnten und 
evtl. Vorschläge zur Verbesserung macht. Vielen Dank im voraus.
1
#include <avr/power.h>
2
#include <avr/wdt.h>
3
#include <avr/sleep.h>
4
#include <avr/interrupt.h>
5
6
#define MASK_SENSOR  (1<<PB4)
7
#define MASK_LED     (1<<PB3)
8
#define TOTAL_INPUTS  3
9
10
void wdt_init() {
11
    cli();
12
    wdt_reset();
13
    WDTCR = (1<<WDE) | (1<<WDCE);   // Enable watchdog
14
    WDTCR = (1<<WDIE) | WDTO_4S;    // Watchdog interrupt instead of reset with 4s timeout
15
    sei();
16
}
17
18
void sleep_now() {
19
    power_all_disable();
20
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
21
    sleep_enable();
22
    sleep_mode();
23
    sleep_disable();
24
    wdt_init();
25
}
26
27
int main(void) {
28
    int i;
29
30
    // SETUP
31
    DDRB |= MASK_BUZZER | MASK_LED;                     // Set buzzer and led pin to output
32
    for(i=0; i<TOTAL_INPUTS; ++i) calibrate_sensors(i); // Set sensor pins and calibrate them (all digital inputs with enabled pull-ups)
33
34
    wdt_init();
35
36
    // MAIN LOOP
37
    while( 1 ) {
38
        get_sensor_data(); // full of wdt_resets()
39
        sleep_now();
40
    }
41
42
    return 0;
43
}

von Christoph -. (con-f-use)


Lesenswert?

Okay ein Update: Mit diesem Code scheint der Chip einen reset zu machen, 
anstatt einfach nur aus dem Schlaf zu erwachen. Weiß aber nicht woran 
das liegt, weil ja WDIE eingeschaltet ist. Wäre für jede Hilfe dankbar.

von Hanno (Gast)


Lesenswert?

Zum Aufwachen aus dem Schlaf kann man je nach Modus jeden Interrupt 
benutzen, z.B. auch einen normalen Timer-Overflow-Int. - Scheint mir der 
saubere Weg zu sein, anstatt den Watchdog für sowas zu missbrauchen.

Grüße
 Hanno

von Thomas E. (thomase)


Lesenswert?

Hanno schrieb:
> Zum Aufwachen aus dem Schlaf kann man je nach Modus jeden Interrupt
> benutzen, z.B. auch einen normalen Timer-Overflow-Int.
Nein. Kann man nicht.

Hanno schrieb:
> anstatt den Watchdog für sowas zu missbrauchen.
Blödsinn.

Christoph -. schrieb:
> Mit diesem Code scheint der Chip einen reset zu machen,
Wo ist deine "ISR(WDT_vect)"? Die brauchst du natürlich, sonst springt 
er beim Interrupt auf den Reset-Vektor.

mfg.

von Watchdog (Gast)


Lesenswert?

Nee, ohne ISR macht der normalerweise einfach gar keinen ISR, weckt aber 
trotzdem. Mag je nach Compiler anders sein.
Und der WDT ist toll für sowas, da geb' ich Thomas recht.
Ist bei den Fuses der Watchdog aktiviert? Wenn ja: Abschalten.

von Thomas E. (thomase)


Lesenswert?

Watchdog schrieb:
> Nee, ohne ISR macht der normalerweise einfach gar keinen ISR, weckt aber
> trotzdem. Mag je nach Compiler anders sein.
So einfach ist das nicht.
Wird ein Interrupt ausgelöst, egal welcher, wird der Program Counter des 
Controllers auf den Interrupt-Vektor gesetzt. Dann wird der Befehl 
ausgeführt, der da steht. Da kann der Compiler gar nichts gegen machen. 
Das ist reine Hardware.
Üblicherweise steht dort ein Jump auf die ISR.
Ist keine ISR angelegt, wird ein Bad Interrupt ausgeführt, der wiederum 
einen Jump auf 0 enthält. Sozusagen ein Warmstart. AVR-GCC.
Vielleicht machen das andere Compiler anders. Keine Ahnung. 
Assemblerporgrammierer würden in diesem Falle einfach ein reti auf den 
Interrupvektor schreiben.

mfg.

von Watchdog (Gast)


Lesenswert?

Oops... Hast recht, gerade nochmal ausprobiert. Ich dachte ich hätte das 
schonmal gemacht, aber da hat mich meine Erinnerung getrogen. Sorry!


Christoph: Ergänze irgendwo

ISR(WDT_vect) { }  //WatchDogTimer interrupt

von Christoph -. (con-f-use)


Lesenswert?

Vielen Dank euch allen! Werde es morgen mal probieren. Habe mir schon 
gedacht, dass ich etwas offensichtliches vergessen hab.

@Hanno: Aus den anderen sleep modi reicht je nach Chip meistens jeder 
interrupt. Bei power_dwn ist allerdings der watchdog gefragt, besonders, 
weil der seinen eigenen Timer mitbringt.

von Christoph -. (con-f-use)


Lesenswert?

Der Vollständigkeit halber: Das Problem war tatsächlich die fehlender 
ISR(wdt_vec). Fehlt das, wird ein reset vorgenommen.

Danke an alle Beteiligten.

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.