Forum: Mikrocontroller und Digitale Elektronik sleep und Interrupt


von Henry (Gast)


Lesenswert?

Hallo
Es wird auf Mikrokontroller die Funktion sleep und Interrupt 
vorgestellt.
Dabei wird dieses Programm für den Atmega32 als Beispiel angegeben:
1
/*************************************************************************
2
* Sleep Mode Demo, Power Down Mode ATmega32 mit internem 1 MHz Oszillator
3
* LOW Fuse Byte = 0xE1 An PD5 muss eine LED mit 1 kOhm Vorwiderstand angeschlossen werden An PD2 muss ein Taster gegen GND angeschlossen sein
4
*************************************************************************/
5
#define F_CPU 1000000
6
#include <avr/io.h>
7
#include <avr/sleep.h>
8
#include <avr/interrupt.h>
9
#include <util/delay.h>
10
// lange, variable Wartezeit, Einheit in Millisekunden
11
void long_delay(uint16_t ms) 
12
  {
13
    for (; ms>0; ms--) _delay_ms(1);
14
  }
15
int main (void) 
16
  {   // IO konfigurieren
17
    DDRA = 0xFF;
18
    DDRB = 0xFF;
19
    DDRC = 0xFF;
20
    DDRD = 0xFB;            // PD2 = INT0 = Eingang
21
    PORTD = 0x04;           // Pull Up aktivieren
22
    // Analogcomparator ausschalten
23
    ACSR = 0x80;
24
    // Interrupt konfigurieren
25
    MCUCR &= ~0x3;                // levelgesteuerter Interrupt an INT0
26
    // Interrupts freigeben
27
    sei();
28
    // Endlose Hauptschleife
29
    while(1) 
30
      {
31
        GICR |= (1 << INT0);              // externen Interrupt freigeben
32
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
33
        sleep_mode();                     // in den Schlafmodus wechseln
34
        // hier wachen wir wieder auf
35
        GICR &= ~(1 << INT0);             // externen Interrupt sperren
36
        // WICHTIG! falls der externe LOW Puls an INT0 sehr lange dauert
37
        PORTD |= (1 << PD5);            // LED für eine Sekunde anschalten
38
        long_delay(1000);
39
        PORTD &= ~(1 << PD5);
40
      }
41
}
42
43
// externer Interrupt INT0 
44
// Die Interruptroutine kann leer sein, ABER sie muss existieren! Sonst springt der AVR nach // dem Aufwachen zum Reset, weil kein sinnvoller  Interruptvektor eingetragen ist!
45
ISR(INT0_vect) 
46
  {
47
  }
Versuche dieses Programm nun für den Attiny841 zu übersetzen.
Dabei liegt die LED auf PA3 und der Taster auf PB2 (nach GND).
Da die Bezeichnungen der einzelnen Register sich wieder unterscheiden 
oder eben anders sind, klappt es nicht. Mein Code bisher:
1
 
2
#define F_CPU 16000000UL    // Angabe der Frequenz, wichtig für die Zeit
3
#include "util/delay.h"      // Einbindung Datei Pause
4
#include "avr/io.h"        // Einbindung Datei Ausgänge
5
#include "avr/sleep.h"
6
#include "avr/interrupt.h"
7
8
int main (void)
9
{   // IO konfigurieren
10
  DDRA=0b00001000;      // DDR A auf Ausgang schalten
11
  PORTA=0b00001000;      // Port A auf aus
12
  DDRB = 0b00000000;            // PD2 = INT0 = Eingang
13
  PORTB=0b00000000;      // Port A auf aus
14
  // Interrupt konfigurieren
15
  MCUCR |= (1<<ISC01)|(1<<ISC00);                // levelgesteuerter Interrupt an INT0
16
  // Interrupts freigeben
17
  sei();
18
  // Endlose Hauptschleife
19
  while(1)
20
    {
21
      GIFR |= (1 << INT0);            
22
    PCMSK1 |= (1 << PCINT10);              // externen Interrupt freigeben
23
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);
24
      sleep_mode();                     // in den Schlafmodus wechseln
25
    // hier wachen wir wieder auf
26
      GIFR &= ~(1 << INT0);           
27
    PCMSK1 &= ~(1 << PCINT10);             // externen Interrupt sperren
28
    // WICHTIG! falls der externe LOW Puls an INT0 sehr lange dauert  
29
    PORTA |= (1 <<PINA3);            // LED für eine Sekunde anschalten
30
    _delay_ms(1000);
31
    PORTA &= ~(1<<PINA3);      
32
  }
33
}
34
35
ISR(INT0_vect)
36
  {
37
  }
Habe versucht die Änderungen aus dem DB des Attiny841 korrekt 
umzusetzen, leider ohne Erfolg.
Kann mir jemand helfen den fehler zu finden?

von S. Landolt (Gast)


Lesenswert?

Ganz oberflächlich betrachtet: GIFR ist nicht GICR - beim ATtiny841 
befindet sich INT0 in GIMSK.
  Und das Setzen von PCMSK1 ist doch sinnlos, oder?

von Heiner (Gast)


Lesenswert?

@Henry

Mein Gott, Henry!

Du versuchst doch nun schon seit einiger Zeit, auf dem ATiny841 sleep, 
Interrupt, power etc zum Laufen zu bringen.

Lies doch endlich mal das DB

So wird das nie was.
Immer Programme vom Netz hirnlos zusammen kopieren ohne Verständnis bzw. 
Zurate ziehen des Datenblatts und dann um Hilfe schreien, weil das 
kopierte Programm nicht für den Attiny841 ist und daher nicht fkt.

SCNR

von Stefan F. (Gast)


Lesenswert?


von S. Landolt (Gast)


Lesenswert?

Und warum wird aus
MCUCR &= ~0x3;                  // levelgesteuerter Interrupt an INT0

MCUCR |= (1<<ISC01)|(1<<ISC00); // levelgesteuerter Interrupt an INT0

? Auch beim ATtiny841 gilt: 'ISC00=0 ISC01=0: The low level of INT0 
generates an interrupt request'.

von Henry (Gast)


Angehängte Dateien:

Lesenswert?

sleep funktioniert korrekt. Kann die verschiedenen Arten einstellen und 
den Strom dabei messen. Komme auf ca. 0,2mA. Das aufwecken mit Watchdog 
funktioniert ebenfalls. Das nächste was dazu kommen soll, ist aufwecken 
mit Taster und Timer. Das DB habe ich mehmals studiert. Leider komme ich 
bei diesem DB mit den unterschiedlichen Register nicht klar. Deshalb 
frage ich einfach ob mir jemand helfen kann.

Stefan ⛄ F. schrieb:
> Wo ist eigentlich die Doku von avr/interrupt.h für den ATtiny841?

Sorry, das versteh ich nicht so ganz. Habe mir die Datei interrupt.h 
angesehen. Damit die Funktionen von sleep gehen ist ja interrupt 
notwendig. Ansonsten steht doch das in GCC drin.

von Henry (Gast)


Lesenswert?

S. Landolt schrieb:
> ? Auch beim ATtiny841 gilt: 'ISC00=0 ISC01=0: The low level of INT0
> generates an interrupt request'.

Habe das aus der Beschreibung des Registers so rausgelesen. Schau gleich 
nach

von Stefan F. (Gast)


Lesenswert?

Henry schrieb:
>> Wo ist eigentlich die Doku von avr/interrupt.h für den ATtiny841?
> Sorry, das versteh ich nicht so ganz

Danach habe ich gefragt, weil ich dort immer nachschaue, wie die ISR 
heißen muss. Aber wie gesagt enthalten beide Dokumente gar keine Angaben 
zum ATtiny841.

> Habe mir die Datei interrupt.h angesehen.

Wenn du das daraus ableiten kannst: gut.

Ich habe eine ältere Version, die deinen ATtiny nicht unterstützt. Da 
kann ich natürlich nichts finden. Ich hätte die Angaben allerdings 
wenigstens in der Tabelle in der online Doku von Microchip erwartet - wo 
sonst?

von S. Landolt (Gast)


Angehängte Dateien:

Lesenswert?

> Habe das aus der Beschreibung des Registers so rausgelesen.

Wo soll da der Unterschied sein?
Und was ist mit meinem Hinweis auf GIMSK?

von Georg M. (g_m)


Lesenswert?

Henry schrieb:
> der Taster auf PB2 (nach GND).

PB1

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.