Forum: Mikrocontroller und Digitale Elektronik Atmega resettet nach SleepMode


von Rene V. (hhnf)


Lesenswert?

Guten Morgen! :-)
Ich möchte einen Atmega328P (aus altem Arduino Board) alle 8 Sekunden 
mit den Timer2 (asynchron 32,768kHz) aus dem Power Save Mode aufwecken:

1
#include "Defines.h"
2
3
ISR(TIMER2_COMPA_vect)
4
{
5
  TCCR2B = TCCR2B;
6
  TCNT2 = 0;
7
  while(ASSR & ((1<<TCN2UB) | (1<<OCR2AUB) | (1<<OCR2BUB) | (1<<TCR2AUB) | (1<<TCR2BUB)));
8
}
9
10
void SetupTimer(void)
11
{
12
  DEBUG("Setup Timer 2...\n")
13
  
14
  // Timer 2 konfigurieren (aus AVR-GCC Tutorial)
15
  GTCCR |= (1 << TSM) | (1 << PSRASY);  //Timer anhalten, Prescaler Reset
16
  TCCR2A = (1 << WGM21);                //CTC Modus
17
  TCCR2B |= (1 << CS22) | (1 << CS21)| (1 << CS20);  //Prescaler 1024
18
  OCR2A = 255;
19
  ASSR |= (1 << AS2);                   //Asynchron Mode einschalten
20
  TIMSK2 |= (1<<OCIE2A);                //Enable Compare Interrupt
21
  GTCCR &= ~(1 << TSM);                 //Timer starten
22
  
23
  DEBUG("Timer 2 started...\n")
24
}
25
26
int main(void)
27
{
28
  DEBUG("\n-----\nStart TAGM V1...\n");
29
  
30
  LED_DDR |= (1 << LED); // Setup Output
31
  LED_PORT ^= (1 << LED);  // Toggle LED
32
  SetupTimer();  // Setup and Start Timer
33
  sei();
34
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
35
    
36
  while(1) {
37
    DEBUG("Sleep a while\n")    
38
    sleep_mode();
39
    sleep_disable();
40
    DEBUG("Wake up\n")
41
    _delay_ms(100);
42
    LED_PORT ^= (1 << LED);  // Toggle LED
43
  }
44
    return 0;
45
}


(includes, defines und das Makro DEBUG (sendet Daten an den UART) sind 
in der defines.h definiert)


Der Atmega gibt folgende Ausgabe zurück:
-----
Start TAGM V1...
Setup Timer 2...
Timer 2 started...
Sleep a while
[8 Sekunden später]
Wake up
[100ms später]
Sleep a while
[8 Sekunden später]

-----
Start TAGM V1...
Setup Timer 2...
Timer 2 started...
Sleep a while
[usw.]

Das erste Mal wacht er ordentlich auf, schaltet die LED aus und legt 
sich wieder schlafen. Wenn er dann wieder aufwacht, wird er aber 
resettet, noch bevor er eine Rückmeldung geben kann.

Wenn ich die LED Steuerung auskommentiere, läuft das Programm 
ordentlich.

Kann die Ursache in der Stromversorgung (3.3V mit LP2950) durch den 
plötzlichen Stromanstieg von 0,5mA auf 3,5ma liegen oder ist der Atmega 
Schuld, der den Zugriff auf das IO Register noch nicht mag? Hab ich 
vielleicht irgendetwas entscheidendes beim Sleep Mode übersehen.

Vielen Dank!

von c-hater (Gast)


Lesenswert?

Rene V. schrieb:

> ISR(TIMER2_COMPA_vect)
> {
>   TCCR2B = TCCR2B;
>   TCNT2 = 0;
>   while(ASSR & ((1<<TCN2UB) | (1<<OCR2AUB) | (1<<OCR2BUB) | (1<<TCR2AUB)
> | (1<<TCR2BUB)));
> }

Bitte Inhalt der ISR vollständig entsorgen. Der ist schlicht kompletter 
Nonsense. Woher hast du denn diesen Unsinn kopiert?

Die ISR sollte so aussehen:

ISR(TIMER2_COMPA_vect) {}

und sie macht dann schon alles, was sie machen muß.


> int main(void)
...
>   set_sleep_mode(SLEEP_MODE_PWR_SAVE);
>
>   while(1) {
>     sleep_mode();
>     sleep_disable();
...

Das ist auch Unsinn.

Entweder, du verzichtest auf den Aufruf von sleep_disable in der 
Hauptschleife oder du packst auch den Aufruf von set_sleep_mode mit in 
die Hauptschleife.

Und, last but not least, die Wahl des Schlafmodus ist auch ziemlich 
unsinnig. Da kann man auch fast wach bleiben...

Richtig Strom gespart wird nur in PowerDown.

Die einzige Erklärung wäre: Da soll noch was anderes laufen. Nun, wenn 
da noch was anderes läuft, dann findest du DORT auch den Grund für den 
Reset...

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.