Forum: Mikrocontroller und Digitale Elektronik Atmega328P - WatchDog - SLEEP_MODE - 8 Sekunden


von mamamia (Gast)


Lesenswert?

Hallo,

ich versuche gerade einen Atmega328P in den Schlafmodus 
(SLEEP_MODE_PWR_DOWN) zu bringen. Ein WatchDog soll den uC alle 8sec 
wieder aus dem Modus wecken.

Das WDTCSR Register setze ich auch wie im Datenblatt angeben auf 
B00100001.

Leider schläft dieser lediglich 4 Sekunden anstatt die gewünschten 8 
Sekunden.

Eckdaten: Der uC hat einen 16Mhz Quarz und läuft mit 5V.

Ich weiß leider nicht wie ich das in den Griff bekomme. Evtl. hat jemand 
einen Tipp für mich.

Gruß

von g457 (Gast)


Lesenswert?

> Das WDTCSR Register setze ich auch wie im Datenblatt angeben auf
> B00100001.

Wie setzt Du das ∗genau∗?

von mamamia (Gast)


Lesenswert?

Hier mein Setup für den WatchDog:

// Clear MCUSR, WDRF reset
MCUSR = MCUSR & B11110111;

// Setzen von WDCE und WDE
WDTCSR = WDTCSR | B00011000;

// Setzen des Prescaler. WDP0 und WDP3 auf 1 setzen. (8 sekunden)
WDTCSR = B00100001;

// Enable the watchdog timer interupt.
WDTCSR = WDTCSR | B01000000;

von M. K. (sylaina)


Lesenswert?

mamamia schrieb:
> Leider schläft dieser lediglich 4 Sekunden anstatt die gewünschten 8
> Sekunden.

Aus dem Kopf wette ich, dass es 4,3 Sekunden sind…Datenblatt lesen!!!

von mamamia (Gast)


Lesenswert?

Hmm???

Ich lese das Datenblatt nun zum x-ten Mal. Ich finde die Lösung nicht.

Vielleicht kannst du mir auf die Sprünge helfen?

von mamamia (Gast)


Lesenswert?

Liegt es evtl. an der Betriebsspannung?

- The frequency of the Watchdog Oscillator is voltage dependent

Allerdings wenn ich das dazugehörige Diagramm ansehe (Watchdog 
Oscillator Frequency vs. VCC), dann würde ja die Frequenz mit sinkender 
Spannung größer werden.

Ein Zyklus würde ja dann eher noch schneller werden???

Hee???

von Thomas E. (thomase)


Lesenswert?

mamamia schrieb:
> MCUSR = MCUSR & B11110111;
Was soll das denn bewirken?
Wo ist B11110111 definiert?
int B11110111 = 0; ???

mfg.

von Lucky (Gast)


Lesenswert?

WDTCSR = B00111001;  //set WDCE to change prescaler
WDTCSR = B00101001;  //clear WDCE

Versuch das mal.

von mamamia (Gast)


Lesenswert?

Lucky schrieb:
> WDTCSR = B00111001;  //set WDCE to change prescaler
> WDTCSR = B00101001;  //clear WDCE

Das gleiche Verhalten.

Der WatchDog kommt nach 4,x Sekunden wieder aus seinem Tiefschlaf.

Ich habe jetzt auch mal die Versorgungsspannung von 5V auf 3,3V 
geändert.

Nach wie vor erreiche ich nicht die 8 Sekunde.

von Michi (Gast)


Lesenswert?

mamamia schrieb:
> Der WatchDog kommt nach 4,x Sekunden wieder aus seinem Tiefschlaf.
Kann der Watchdog auch schlafen?

von mamamia (Gast)


Lesenswert?

Michi schrieb:
> mamamia schrieb:
>> Der WatchDog kommt nach 4,x Sekunden wieder aus seinem Tiefschlaf.
> Kann der Watchdog auch schlafen?

Vielleicht hätte ich schreiben sollen, das der Hund alle 4s bellt - 
anstatt alle 8s.

von Uwe (de0508)


Lesenswert?

Wird das Programmstück überhaubt übersetzt?
Bei den Zuweisungen handelt es sich nicht um Konstanten !
Und wie sieht das Stück Assemblercode aus ?

von mamamia (Gast)


Lesenswert?

Uwe S. schrieb:
> Wird das Programmstück überhaubt übersetzt?
> Bei den Zuweisungen handelt es sich nicht um Konstanten !
> Und wie sieht das Stück Assemblercode aus ?

Ich kann auch schreiben:

WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = (1<<WDE) | (1<<WDP3) | (1<<WDP0);

das sollte eigentlich das gleiche Verhalten haben wie obige 
Schreibweise.

...

Wenn ich zum Beispiel den Wert auf 4 Sekunden setze:

mit

WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = (1<<WDE) | (1<<WDP3);

dann werden 2 Sekunden daraus.

von Uwe (de0508)


Lesenswert?

Hallo,

besser von der Schreibweise, überprüfe ich jetzt nicht.

Du gehst auf meine Fragen nicht ein !

Noch mal deutlicher: B00111001 ist keine Konstante in "C" !

von mamamia (Gast)


Lesenswert?

Uwe S. schrieb:
> Noch mal deutlicher: B00111001 ist keine Konstante in "C" !

Ja, da stimme ich dir zu.

B00111001 soll einfach ein Binärwert darstellen.

Ich hätte vermutlich auch einen Hexadezimal Wert (0x39) angeben können 
und diesen dem Register zuweisen können.

von Uwe (de0508)


Lesenswert?

Hallo,

ich würde die in avr gcc vorhandenen Macros verwenden.

http://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Watchdog

Dann müsste man sich auch mit dem Timing der Befehlsabfolge auseinander 
setzen.
1
 #include <avr/wdt.h> 
2
 wdt_enable(WDTO_8S);
3
 wdt_reset();

von Uwe (de0508)


Lesenswert?

Hallo,

im Datenblatt zum atmega328p
stehen die genaue Reihenfolge der Anweisungen in C.
S.53f,S.56
1
void WDT_Prescaler_Change(void)
2
{
3
  __asm__ __volatile__ ("cli")
4
  __asm__ __volatile__ ("wdr")
5
6
  /* Start timed sequence */
7
  WDTCSR |= (1<<WDCE) | (1<<WDE);
8
9
  /* Set new prescaler(time-out) value = 1024K (1048576) cycles (~8 s) */
10
  WDTCSR = (1<<WDE) | (1<<WDP3) | (0<<WDP2) | (0<<WDP1) | (1<<WDP0);
11
12
  __asm__ __volatile__ ("sei")
13
}
1
void WDT_off(void)
2
{
3
  __asm__ __volatile__ ("cli")
4
  __asm__ __volatile__ ("wdr")
5
6
  /* Clear WDRF in MCUSR */
7
  MCUSR &= ~(1<<WDRF);
8
9
  /* Write logical one to WDCE and WDE */
10
  /* Keep old prescaler setting to prevent unintentional time-out */
11
  WDTCSR |= (1<<WDCE) | (1<<WDE);
12
13
  /* Turn off WDT */
14
  WDTCSR = 0x00;
15
16
  __asm__ __volatile__ ("sei")
17
}

von mamamia (Gast)


Lesenswert?

Problem gelöst!

von Uwe (de0508)


Lesenswert?

Hallo,

sei so nett und beschreibe, wie das Problem gelöst wurde, so könnten 
auch anderer Leser davon profitieren.

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.