Atmega328p Sleep-Modus, ich komme nicht weiter

Persönliche Seite #3814350
Lesenswert?

Ich komme nicht weiter und bitte um Hilfe.

Ich möchte einen At328p in den Schlafmodus versetzen und nach 60 
Sekunden wieder aufwecken. Timer2 zählt, solange der Atmega nicht im 
Schlafmodus ist.
Am Timer2 hängt ein 32.768Khz Uhrenquarz.

Sobald ich:
----------schnipp-------------
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
sleep_mode();      // in den Schlafmodus wechseln
---------schnapp--------------
aktiviere, bleiben die LED's für immer dunkel.

Was mache ich falsch?

Danke im Vorraus.
Angehängte Dateien:
#3814378
Lesenswert?

1
void timer2_init(void)
2
{
3
 ASSR = (0<< AS2);               // Timer2 asynchron takten

?

0 geshiftet um was_weiß_ich_was ist immer suspekt.
Laut Datenblatt willst du das Bit allerdings auf 1 haben, um den Timer 
auf asynchron zu schalten. Und nur dann kommst du auch aus dem Power 
Save wieder raus.
(Firma: Vescomp) #3814390
Lesenswert?

Stefan B. schrieb:
> Sobald ich:
> ----------schnipp-------------
> set_sleep_mode(SLEEP_MODE_PWR_SAVE);
> sleep_mode();      // in den Schlafmodus wechseln
> ---------schnapp--------------
> aktiviere, bleiben die LED's für immer dunkel.

 Und so ?
1
----------schnipp-------------
2
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
3
///////////////////////////////
4
sleep_enable();          // MCUCR mitteilen, was du vorhast
5
//////////////////////////////
6
sleep_mode();      // in den Schlafmodus wechseln
7
---------schnapp--------------
Persönliche Seite #3814408
Lesenswert?

Karl Heinz schrieb:
> 0 geshiftet um was_weiß_ich_was ist immer suspekt.

Oha, ja, das war ein Fehler....

Ich habs jetzt auf:  ASSR = (2<< AS2);   geändert.

Marc Vesely schrieb:
> sleep_enable();

Habs mal eingebaut, funktioniert aber trotzdem nicht.

Es wäre auch möglich gewesen, dass die Sekunden >=60 nicht auf Null 
gesetzt werden, ist aber auch nicht der Fall.

Ich hab beim µc den Wecker mal bei Sekunde 59 klingeln lassen. Die LED's 
bleiben trotzdem dunkel.
#3814846
Lesenswert?

Stefan B. schrieb:
> Ich habe es jetzt so gelöst, indem ich den Atmega8L erstmal verwende,
> bis ich ne Lösung zum Atmega328p-Problem gefunden habe.
Hoffentlich.

Mir erschliesst sich sich zwar nicht, warum du ständig die Interrupts 
abschaltest, aber wenn schon, dann solltest du sie auch wieder 
einschalten.
1
void read_adc (void)
2
{
3
 sei(); //Activate interrupts
4
 setup_adc();
5
 cli();
6
}

Ich kann beim besten Willen die Stelle nicht finden, wo sie wieder 
eingeschaltet werden. Dann kannst du natürlich lange auf deine 
Timerinterrupts warten.

Im Gegensatz dazu hast du das beim 8er aber gemacht:
1
void schlafmodus (void)
2
{
3
sei();    
4
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
5
sleep_enable();
6
sleep_mode();
7
sleep_disable();
8
cli();
9
}

während du den 328er nicht schlafen, sondern ins Koma schickst:
1
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
2
        sleep_mode();

Ein sleep_enabale(); hab ich auch nirgends gesehen.

mfg.

PS: Den Code vernünftig einrücken, sieht nicht nur hübscher aus, sondern 
liest sich auch besser.
(Firma: Vescomp) #3814983
Lesenswert?

Stefan B. schrieb:
> Der Vollständigkeit halber im Anhang noch das main-File vom Atmega8L.
1
void schlafmodus (void)
2
{
3
    sei();    
4
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
5
    sleep_enable();
6
    sleep_mode();
7
    sleep_disable();
8
    cli();
9
}

 Ich würde es so probieren:
1
   sleep_enable();
2
   set_sleep_mode(SLEEP_MODE_PWR_SAVE);
3
   sei();
4
   sleep_cpu();  //Put the device into sleep mode. The SE bit must be set
5
               // beforehand, and it is recommended to clear it afterwards.
6
   sleep_disable();
7
   cli();
 Da ich nicht weiß, was GCC genau macht, kann ich auch nicht behaupten,
 dass das funktioniert, aber es scheint irgendwie logischer.
 Das ganze in Assembler zu schreiben, wäre viel besser, zumindest bis
 es fehlerfrei läuft.
#3815004
Lesenswert?

Marc Vesely schrieb:
> sleep_enable();
>    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
>    sei();
>    sleep_cpu();
>    sleep_disable();
>    cli();

Warum so kompliziert?
1
int main(void)
2
{
3
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
4
  sleep_enable();
5
  .
6
  .
7
  .
8
  sei();
9

10
  while()
11
  {
12
    .
13
    .
14
    .
15
    if(SleepAllowed)
16
    {
17
       sleep_cpu();
18
       SleepAllowed = 0;
19
    }
20
    .
21
    .
22
  }
23
}

Und die Interrupts werden einmal eingeschaltet und bleiben das auch.

Marc Vesely schrieb:
> Das ganze in Assembler zu schreiben, wäre viel besser, zumindest bis
>  es fehlerfrei läuft.
Unsinn.

mfg.
Persönliche Seite #3815176
Lesenswert?

Erstmal danke für die Tips.

Thomas Eckmann schrieb:
> Mir erschliesst sich sich zwar nicht, warum du ständig die Interrupts
> abschaltest, aber wenn schon, dann solltest du sie auch wieder
> einschalten.

Das ändere ich morgen noch.

Thomas Eckmann schrieb:
> während du den 328er nicht schlafen, sondern ins Koma schickst:
>   set_sleep_mode(SLEEP_MODE_PWR_SAVE);
>         sleep_mode();
>
> Ein sleep_enabale(); hab ich auch nirgends gesehen.

Das Problem ist beim 328er, dass der Timer schon garnicht mit dem im 
ersten Beitrag angehängten C-File läuft und ich habe bis jetzt den 
Fehler noch nicht gefunden.

irgendwo hier drin ist für den 328er noch ein Fehler:

void timer2_init(void)
{
 ASSR = (1<< AS2);               // Timer2 asynchron takten
 long_delay(1000);               // Einschwingzeit des 32kHz Quarzes
 TCCR2A  =  (1<<WGM21);          // CTC-Modus
 TCCR2B  = (1<<CS22)|(1<<CS20); // Vorteiler=128
 while((ASSR & (1<< TCR2AUB))); // Warte auf das Ende des Zugriffs
 TIFR2   = (1<<OCF2A);          // Interrupt löschen (*)
 TIMSK2 |= (1<<OCIE2A);         // Timer Compare Match Interrupt 
freischalten
// (*) "Alternatively, OCF2 is cleared by writing a logic one to the 
flag."
 OCR2A=NormalerCompwert;
 while((ASSR & (1<< OCR2AUB))); // Warte auf das Ende des Zugriffs
}

Falk Brunner schrieb:
> Siehe Sleep Mode.

Hi Falk, ähhm, habe ich schon mehrfach durchgelesen.

Thomas Eckmann schrieb:
> Warum so kompliziert?
> int main(void)
> {
>   set_sleep_mode(SLEEP_MODE_PWR_SAVE);
>   sleep_enable();
>   .

Danke Thomas, das probiere ich morgen mal aus.

Aber mein größtes Problem ist, dass die ganze Geschichte nicht auf dem 
328er funktionieren will. Ich würde den lieber benutzen als den Atmega8, 
da wie gesagt, beim Atmega8 bei unter 2.7 Volt schluss ist und der 328er 
funzt noch mit 1.7 Volt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren