Forum: Mikrocontroller und Digitale Elektronik Atmega328p Sleep-Modus, ich komme nicht weiter


von Stefan B. (sibbl) Benutzerseite


Angehängte Dateien:

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.

von Karl H. (kbuchegg)


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.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


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--------------

: Bearbeitet durch User
von Stefan B. (sibbl) Benutzerseite


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.

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:
> 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.

Tippfehlere hier im Forum, oder warum die 2?

von Stefan B. (sibbl) Benutzerseite


Lesenswert?

Ich glaube, ich komme der Sache näher.
Nein, das war kein Tippfehler. Hab nochmal nachgesehen.

So stehts jetz drin: ASSR = (1<< AS2);

Allerdings zählt jetzt der Timer nichtmehr.

Ähhm, Hardware kanns nicht sein, ich habe vorhin das ganze mit nem 
Atmega8 getestet, da funktioniert es. Nur funzt der Atmega8 nicht unter 
2,7 Volt.

: Bearbeitet durch User
von Stefan B. (sibbl) Benutzerseite


Angehängte Dateien:

Lesenswert?

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

Der Vollständigkeit halber im Anhang noch das main-File vom Atmega8L.

Grüße....

von Thomas E. (thomase)


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.

von Marc V. (Firma: Vescomp) (logarithmus)


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.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Siehe Sleep Mode.

von Thomas E. (thomase)


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.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Thomas Eckmann schrieb:
> Unsinn.

 Und warum ?
 Weil das ganze nur auf paar bits setzen und rücksetzen hinausläuft ?

von Thomas E. (thomase)


Lesenswert?

Marc Vesely schrieb:
> Weil das ganze nur auf paar bits setzen und rücksetzen hinausläuft

Und das geht in C nicht?
Ausserdem habe ich geschrieben, wie man es richtig macht.

Friggel weiter!

von Stefan B. (sibbl) Benutzerseite


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.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Thomas Eckmann schrieb:
> Ausserdem habe ich geschrieben, wie man es richtig macht.

 Ich bewundere deine C-kenntnisse.
 Wahrscheinlich schon hart an der Grenze mit diesem (abgeschriebenem)
 Schnipsel. Viel weiter wirst du eh nicht kommen.

: Bearbeitet durch User
von Stefan B. (sibbl) Benutzerseite


Lesenswert?

Warum denn immer diese Stichelei?

Ich persönlich hätte auch nie gedacht, dass ich anfangs mit meinen 
nullkommanull-Kenntnissen überhaupt soweit komme....hehe

von Thomas E. (thomase)


Lesenswert?

Marc Vesely schrieb:
> Viel weiter wirst du eh nicht kommen.

Ach Vesy, YMMD

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.