Forum: Mikrocontroller und Digitale Elektronik Attiny2313 PowerDown und Wakeup mit INT0 geht nicht


von C. H. (hedie)


Lesenswert?

Hallo zusammen...

Ich versuche meinen ATTiny 2313 in den PowerDown Modus zu versetzen und 
durch eine positive Flanke am INT0 pin wieder aufzuwecken...

Doch leider klappt das nicht...

Hier mein bisheriger code
1
ISR(INT0_vect)
2
{
3
  sleep_disable();
4
  cli();
5
  return;
6
}
7
8
9
10
int main(void)
11
{
12
13
//.... sonstiger code
14
15
PCMSK |= (1<<PIND2);
16
MCUCR = (1<<ISC01) | (1<<ISC00);
17
GIMSK  |= (1<<INT0);
18
19
delay_ms(3000);
20
21
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
22
sleep_enable();
23
sei();
24
sleep_cpu();
25
26
27
while(1)
28
{
29
  //.... Hier steht mein Code welcher beim aufruf des Interrupts bzw. danach abgearbeitet werden soll....
30
31
32
sleep_enable();
33
sei();
34
sleep_cpu();
35
}
36
37
}

Der Stromverbrauch sinkt nach 3 sekunden von ca 2mA auf ein paar uA

Doch leider erweckt eine Positive Flanke den Attiny nicht aus dem 
schlaf...


Wo liegt hier wohl der Fehler?

Der UART ist auch aktiv... Jedoch nur TXD nicht RXD!
Der INT0 ist der einzige Interrupt.

Danke schonmal

von Thomas E. (thomase)


Lesenswert?

Claudio Hediger schrieb:
> Doch leider erweckt eine Positive Flanke den Attiny nicht aus dem
>
> schlaf...
>
> Wo liegt hier wohl der Fehler?

Du hast diese Fußnote

>Notes:
>2. For INT0, only level interrupt.

im Datenblatt nicht gelesen.


mfg.

von C. H. (hedie)


Lesenswert?

Thomas Eckmann schrieb:
> Du hast diese Fußnote
>
> Notes:
> 2. For INT0, only level interrupt.
>
> im Datenblatt nicht gelesen.
>
>
> mfg.

Ich dachte das bedeutet, das es auf jede Level änderung reagiert oder 
etwa nicht?

von Thomas E. (thomase)


Lesenswert?

Claudio Hediger schrieb:
> Ich dachte das bedeutet, das es auf jede Level änderung reagiert oder
> etwa nicht?

Ja. Und das ist das einzige, was geht.
Denn zur Flankenerkennung braucht er den Takt. Und der ist abgeschaltet.

mfg.

von C. H. (hedie)


Lesenswert?

Thomas Eckmann schrieb:
> Ja. Und das ist das einzige, was geht.
> Denn zur Flankenerkennung braucht er den Takt. Und der ist abgeschaltet.
>
> mfg.

das würde mir ja bereits genügen....

normalerweise liegt 0V als low am INT0 an.... und wenn ich eine Taste 
drücke, so wechselt der PIN von low -> High... somit müsste der Tiny 
doch aufwachen oder?

Tut er aber nicht...

von Thomas E. (thomase)


Lesenswert?

Claudio Hediger schrieb:
> normalerweise liegt 0V als low am INT0 an.... und wenn ich eine Taste
> drücke, so wechselt der PIN von low -> High... somit müsste der Tiny
> doch aufwachen oder?

Das täte er auch, wenn "Logical Change" eingestellt wäre.

Nicht
>MCUCR = (1<<ISC01) | (1<<ISC00);

sondern

MCUCR |= (1 << ISC00);


Und das funktioniert auch nicht so, wie erhofft:
ISR(INT0_vect)
{
  sleep_disable();
  cli();
  return;
}

Das "cli();" ist wirkungslos, da nach dem return aus der ISR der Zustand 
vor dem Eintritt wiederhergestellt wird und da waren die Global 
Interrupts enabled. Das "return" mußt du da auch nicht hinschreiben.

Das "cli();" gehört dorthin:

>sleep_enable();
>sei();
>sleep_cpu();
cli();
>}
>}

Sonst ruft der prellende Taster die ISR x-mal auf.

mfg.

von C. H. (hedie)


Lesenswert?

Vielen Dank für deine Hilfe...

Doch leider klappt es immer noch nicht... ich kann den Tiny nicht 
aufwecken...

von Ralf2008 (Gast)


Lesenswert?

Muss das SE bit im MCUCR-Register nicht auch noch gesetzt werden?

Ralf2008

von Thomas E. (thomase)


Lesenswert?

Claudio Hediger schrieb:
> Doch leider klappt es immer noch nicht... ich kann den Tiny nicht
> aufwecken...

Dann müssen wir mal genauer gucken.´

Ralf2008 schrieb:
> Muss das SE bit im MCUCR-Register nicht auch noch gesetzt werden?
Das wird gesetzt. Sogar zweimal: sleep_enable();

Claudio Hediger schrieb:
> set_sleep_mode(SLEEP_MODE_PWR_DOWN);
> sleep_enable();
> sei();
> sleep_cpu();

> while(1)
> {
>   //.... Hier steht mein Code...
>
> sleep_enable();
> sei();
> sleep_cpu();

Das ist auch ein bisschen viel des Guten. Und gleichzeitig etwas zu 
wenig.

Das reicht:

>Pin Change Interrupt. Hat mit INT0 nichts zu tun
//PCMSK |= (1<<PIND2);

>Mit einen "=" musst du immer vorsichtig sein, besser ist "|="
MCUCR |= (1<<ISC01) | (1<<ISC00);
GIMSK  |= (1<<INT0);

>Und das wichtigste fehlt:

DDRD |= (1 << 2);

>Überflüssig:
//delay_ms(3000);

set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();

while(1)
{
   sei();
   sleep_cpu();
   cli();
>   //.... Hier steht mein Code...
}

Und nicht Doppelt-und Dreifachaufrufe für ein und dasselbe.

Das mit dem ständigen sei() und cli() ist natürlich auch nicht das 
Wahre. Aber das ist erstmal nur Kosmetik. Aufwachen sollte er jetzt.

mfg.

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.