Atmega328p wacht nicht auf, wo steckt der Fehler?

Gast #3907719
Lesenswert?

Hallo,
ich möchte meinen MCU alle 2 Sekunden wecken, um ein Sensor kurz zu 
überprüfen und dann wieder schlafen legen lassen. Zusätzlich habe ich in 
der ISR eine Countdown Schaltung programmiert. Mit dem Flag zeige ich an 
wann der MCU alarmieren soll. Leider glaube ich das der MCU gar nicht 
aus dem Schlafmodus aufwacht, denn der Sensor reagiert nicht mehr und 
der Stromverbrauch ist konstant bei 42µA.

1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
#include <avr/sleep.h>
5
#include <util/delay.h>
6

7
#define F_CPU 8000000L 
8

9
volatile uint8_t flag;
10

11
int main(void)
12
{
13

14
 
15

16
 
17
 DDRC |= (1<<PC5) | (1<<PC4); 
18
 DDRC &= ~(1<<PC3);
19
 
20
 
21
 GTCCR |= (1<<TSM) | (1<<PSRASY);
22
 ASSR |= (1<<AS2); 
23
 TCCR2A |= (1<<WGM21); 
24
 TCCR2B |= (1<<CS22) | (1<<CS21); 
25
 OCR2A = 256-1; 
26
 TIMSK2 |= (1<<OCIE2A); 
27
 GTCCR &= ~(1<<TSM); 
28
 
29

30
 
31
 sei(); 
32
 
33
 
34
 
35
 while(1)
36
    {
37

38
   
39
   set_sleep_mode(SLEEP_MODE_PWR_SAVE);
40
   sleep_mode();
41
 
42
 
43
   
44
   
45
   
46
   PORTC |= (1<<PC4); 
47
   _delay_ms(1); 
48
   
49
   while(!(PINC &= (1<<PINC3)))
50
   {
51
   PORTC |= (1<<PC5); 
52
   }
53
   
54
   PORTC &= ~(1<<PC5); 
55
   PORTC &= ~(1<<PC4); 
56
   
57
   
58
     
59
   while(flag==1)
60
   {
61
   PORTC|= (1<<PC5); 
62
   }
63
   
64
    }
65
 return (0);
66
}
67

68

69

70

71
ISR(TIMER2_COMPA_vect)
72
{
73
 static uint8_t zweitesekunde;
74
 static uint8_t minute=0;
75
 static uint8_t stunde=0;
76
 static uint8_t tag=0;
77
 
78
 zweitesekunde++;
79
 if(zweitesekunde==30)
80
 {
81
 zweitesekunde=0;
82
 minute++;
83
 }
84
    if(minute == 60)
85
    {
86
    stunde++;
87
    minute = 0;
88
    }
89
    if(stunde == 24)
90
    {
91
    stunde = 0;
92
 tag++;
93
 flag=1; 
94
    }
95
 
96
}
Gast #3907769
Lesenswert?

Das erste würde ich so lassen, weil ich solange der Input PINC3 ungleich 
high ist , die LED einschalten möchte und sie auch solange eingeschaltet 
bleiben soll bis der Input wieder zurück auf HIGH geht.

Beim zweiten hast du recht, da die Zeit überschritten wurde und dort die 
LED nur durch resetten zurückgesetzt werden kann.
#3907785
Lesenswert?

David schrieb:
> Das erste würde ich so lassen, weil ich solange der Input PINC3 ungleich
> high ist , die LED einschalten möchte und sie auch solange eingeschaltet
> bleiben soll bis der Input wieder zurück auf HIGH geht.
>
> Beim zweiten hast du recht, da die Zeit überschritten wurde und dort die
> LED nur durch resetten zurückgesetzt werden kann.

Deine Timing-Vorstellungen verstehe ich nicht.
Erst schläfst du 2 Sekunden, dann willst sofort und gleich auf ein 
Eingangssignal reagieren.
Was wenn das Signal innerhalb des 2 Sekundenschlafs kommt?

Funktioniert denn dein Programm ohne Sleep?

Edit:
hier schon geschaut?:
http://www.mikrocontroller.net/articles/Sleep_Mode
Gast #3907813
Lesenswert?

Ja das Programm funktioniert ohne Sleep funktion wunderbar es geht mir 
eigentlich auch nur um die Sleep Funktion.
Ich habe das Programm jetzt einfach mal vereinfacht, damit es um das 
wesentliche geht, das aufwachen:
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
#include <avr/sleep.h>
6

7
#define F_CPU 8000000L
8

9
volatile uint8_t flag;
10

11

12
int main(void)
13
{
14

15
  
16
  //konfigurieren der PINS:
17

18
  
19
  DDRC |= (1<<PC5) | (1<<PC4); //Pin pc5 und pc4 als ausgang definieren
20
  //DDRC &= ~(1<<PC3); //Pin pc3 als eingang definieren
21
  
22
  
23
  //Start der Initalisierung des Timer 2:
24
  GTCCR |= (1<<TSM) | (1<<PSRASY); //Timer anhalten, Prescaler Resetten, um die Einschwingzeit des Oszillators zu überbrücken (Einschwingzeit 100ms-1000ms
25
  ASSR |= (1<<AS2); //Timer Asynchron-Mode einschalten 32768 RTC hängt an XTAL1+XTAL2
26
  TCCR2A |= (1<<WGM21); // Versetze in Compare Mode
27
  TCCR2B |= (1<<CS22) | (1<<CS21); //Prescaler auf 256
28
  OCR2A = 256-1; //(=OCR2A Compare Register) Berechnung der Aufwachzeit (32768/256)^-1*256= Aufwachzeit alle 2 Sekunden wird der MCU aufgeweckt
29
  TIMSK2 |= (1<<OCIE2A); //Timer 2 Interrupt Enable
30
  GTCCR &= ~(1<<TSM); //"Timer anhalten Bit" löschen
31
  
32

33
  
34
  sei(); // Global Interrupt Mode aktiviert
35
  
36
  
37
  
38
  while(1)
39
  {
40
    
41
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
42
    sleep_mode();
43
    
44
    
45
    // Hier wird aufgewacht
46
    
47
    if(flag==1)
48
    {
49
      PORTC |= (1<<PC5); //LED anschalten
50
      _delay_ms(100);
51
      PORTC &= ~(1<<PC5); //LED abschalten
52
      flag=0;
53
    }
54
    
55

56
    
57
  }
58
  return (0);
59
}
60

61

62

63

64
ISR(TIMER2_COMPA_vect)
65
{  
66
  flag=1;
67
}
Gast #3907819
Lesenswert?

Joachim B. schrieb:
> David schrieb:
>> set_sleep_mode(SLEEP_MODE_PWR_SAVE);
>
> womit soll er denn geweckt werden?
>
> möglich wäre:
> Timer 2
> ext. Interrupts
> TWI
> Watchdog
>
> wenn er schläft läuft er nicht mehr....

Deswegen habe ich eigentlich den Timer2 in Compare-Mode programmiert, im 
Power Save Mode sollte dann nur Timer 2 mit einem 32,768khz Quarz laufen 
sobald die 2 Sekunden um sind sollte der Interrupt erfolgen und ihn 
aufwecken, der dann das Hauptorogramm weiter ausführt.
#3907820
Lesenswert?

David schrieb:
> es geht mir
> eigentlich auch nur um die Sleep Funktion.

verstehe ich, nur wenn er schläft schläft er, ich schrieb ja schon die 
Aufwachmöglichkeiten, externer Uhrenquarz am Timer2 32kHz, watchdog, 
oder externer Interrupt.

Ich weiss immer noch nicht wie du den aufwecken willst wenn kein 
watchdaog programmiert ist, kein externer Uhrenquarz dranhängt und kein 
externer Interrupt ausgelöst wird.
#3907843
Lesenswert?

Thomas Eckmann schrieb:
> ???

so ähnlich bei mir auch

also mit sleepmodi hatte ich schon mal das Vergnügen, nur noch nicht mit 
der allgemein beliebten Timer Variante mit dem 32kHz Quarz am extra 
Eingang, nicht dem Systemquarz. Ich las immer davon das der den AVR 
aufwecken kann um alle Skunde die SoftUhr einen weiterlaufen zu lassen. 
Ich bevorzugte die RTC DS3231 die mit ihrem Alarmregister und /INT 
Ausgang am AVR per PCINT weckt, da muss der arme AVR nicht alle Sekunde 
gewckt werden, kann fröhlich pennen bis er wirklich dran ist.
Gast #3907919
Lesenswert?

Chris schrieb:
> Hast du den Quarz zwischen TOSC 1 und TOSC 2?
> Sonst klappt es nicht. Da benötigtst du auch keine extra Kondensatoren.

Ja hab ich.

Der Timer scheint jetzt zu funktionieren. Aber anstatt alle 2 Sekunden 
zu blinken braucht er jetzt fast 10 sekunden?

1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <util/delay.h>
4
#include <avr/interrupt.h>
5
#include <avr/sleep.h>
6

7
#define F_CPU 8000000L
8

9
volatile uint8_t flag;
10

11

12
int main(void)
13
{
14

15
  
16
  //konfigurieren der PINS:
17

18
  
19
  DDRC |= (1<<PC5) | (1<<PC4); //Pin pc5 und pc4 als ausgang definieren
20
  //DDRC &= ~(1<<PC3); //Pin pc3 als eingang definieren
21
  
22
  
23
  //Start der Initalisierung des Timer 2:
24
  GTCCR |= (1<<TSM) | (1<<PSRASY); //Timer anhalten, Prescaler Resetten, um die Einschwingzeit des Oszillators zu überbrücken (Einschwingzeit 100ms-1000ms
25
  ASSR |= (1<<AS2); //Timer Asynchron-Mode einschalten 32768 RTC hängt an XTAL1+XTAL2
26
  TCCR2A |= (1<<WGM21); // Versetze in Compare Mode
27
  TCCR2B |= (1<<CS22) | (1<<CS21); //Prescaler auf 256
28
  OCR2A = 256-1; //(=OCR2A Compare Register) Berechnung der Aufwachzeit (32768/256)^-1*256= Aufwachzeit alle 2 Sekunden wird der MCU aufgeweckt
29
  TIMSK2 |= (1<<OCIE2A); //Timer 2 Interrupt Enable
30
  GTCCR &= ~(1<<TSM); //"Timer anhalten Bit" löschen
31
  
32

33
  
34
  sei(); // Global Interrupt Mode aktiviert
35
  
36
  
37
  
38
  while(1)
39
  {
40
    _delay_ms(500);
41
    PORTC &= ~(1<<PC5); //LED abschalten
42

43
    
44
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);
45
    sleep_mode();
46
    
47
    
48
    // Hier wird aufgewacht
49
    
50

51
    
52
  }
53
  return (0);
54
}
55

56

57

58

59
ISR(TIMER2_COMPA_vect)
60
{  
61
          PORTC |= (1<<PC5); //LED anschalten
62
}

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