Sleep Mode beim ATMega16

Gast #536871
Lesenswert?

Hallo,
Ich möchte mein Projekt (ATMega 16 + Beschaltung) in den "Schlaf" 
versetzen, da ich die Schaltung mit einer Batterie versorgen möchte. 
Folgendes soll geschehen:

Wenn ich 60 Sekunden 'nichts' tue ... also keine Taster drücke (das 
bekomme ich alles hin mit Tastern und so), dann soll der Controller 
schlafen. Laut Tutorial habe ich die Wahl zwischen verschiedenen Arten 
... also Power-Down, Standby und so weiter ... Welche Art würdet ihr mir 
raten ?

Da ist nun von einem Aufweck - Interrup die Rede ... wie Realisiere ich 
soetwas ?

Aus dem Datenblatt wird ersichtlich, dass ich bestimmte Pins am 
Controller beschalten muss ?! IN0 - IN2 ...

Geht es nicht auch so, dass der Controller wieder aufgeweckt wird, wenn 
man irgendeinen Taster betätig, sprich eine Aktion ausführt ?

Möchte IN0 - IN2 nicht unnötig beschalten.

Danke Timo
Gast #536880
Lesenswert?

Je nachdem, welchen Sleep-Mode Du benutzt, bleibt Dir keine andere Wahl, 
als das Aufwecken mit einem externen Interrupt zu realisieren. Je mehr 
Komponenten des Controllers abgeschaltet werden, um Strom zu sparen, 
desto weniger Möglichkeiten zum Aufwecken gibt es. Aus dem 
Power-Down-Modus, in dem auch der Hauptoszillator deaktiviert ist, geht 
das nur über einen Level(!)-Interrupt, da für die Flankendetektierung 
der CPU-Takt benötigt würde. Behelfen kann man sich z.B., indem man alle 
Taster, die den µC aufwecken sollen, über ein UND-Gatter an einen der 
externen Interrupt-Pins legt und den Interrupt vor dem Schlafenlegen als 
Level-Interrupt freigibt. Das wäre die stromsparendste Lösung.
#536915
Lesenswert?

johnny.m wrote:

> der CPU-Takt benötigt würde. Behelfen kann man sich z.B., indem man alle
> Taster, die den µC aufwecken sollen, über ein UND-Gatter an einen der
> externen Interrupt-Pins legt und den Interrupt vor dem Schlafenlegen als
> Level-Interrupt freigibt. Das wäre die stromsparendste Lösung.

Dann doch lieber ein ODER Gatter oder ? ;)

Grüße
Björn
Gast #536922
Lesenswert?

Hallo!

Kommt drauf an wieviel Ansprech zeit du zulassen wills! Ich hab mir 
schon mal so beholfen dass ich den Controller alle 50ms per Timer 
interrupt hab wecken lassen, die Tasten abgefragt hab und in dann wieder 
hab einschlafen lassen.

Die paar µs die der dafür braucht fallen meist nicht ins Gewicht!

MfG Owz
Gast #536968
Lesenswert?

@Björn:
> Dann doch lieber ein ODER Gatter oder ? ;)
Nö. Taster werden bei den AVRs aufgrund der integrierten Pull-Ups 
eigentlich sinnvollerweise immer Low-aktiv angeschlossen. Wenn man die 
Taster an ein UND-Gatter hängt und ein Taster gedrückt wird, so dass die 
UND-Bedingung nicht mehr erfüllt ist, dann gibt das Gatter am Ausgang 
einen Low-Pegel aus. Und das ist genau das, was der Interrupt-Eingang 
braucht...
Gast #579245
Lesenswert?

wenn mein Pic schläft wie wecke ich Ihn wieder auf ohne Flanke am INT 
sondern anch einer bestimmten Zeit.

ich führe einfach nur

Sleep();
aus

aber wie zähle ich jetzt mit ? wenn der Timer aus ist=
Gast #579257
Lesenswert?

Ich verwende einen externen Quarz für den Pic, wenn ich den Timer1 
verwende möchte kann ich diesen quarz nicht mehr verwenden weil sich der 
Pic im schlaf befindet. Muss ich jetzt nochmal einen Quarz verwenden und 
an das RC1 Pin hängen für den Timer1?
#579688
Lesenswert?

Da laut Datenblatt im SLEEP_MODE_PWR_SAVE der Timer2 weiterläuft setzt 
man einfach den nächsten Weckwert und der Prozessor wird zum Zeitpunkt 
wieder aufgeweckt. Interrupt ausführen und dann im Main direkt zurück in 
den sleep.

So z.B.
1
/* weckt den Prozessor alle x ms auf und generiert einen kurzen Impuls auf Ausgang PB0
2
* hier wird mit einem Transistor ein Trafo sekundärseitig angetrieben
3
*
4
*/
5

6

7
#include <avr/io.h>
8
#include <avr/interrupt.h>
9
#include <avr/sleep.h>
10

11

12
#define Set2Output(DataDirection, Pin) DataDirection |=  (1<<Pin)
13
#define Set2Hiz(DataDirection, Pin) DataDirection &= ~(1<<Pin)
14

15
#define Tog_Bit(Port, Pin)  Port ^= _BV(Pin)  //Toggeld Charbit
16
#define Set_Bit(Port, Pin)  Port |= _BV(Pin)  //set Bit
17
#define Clr_Bit(Port, Pin)  Port &= ~_BV(Pin)  //clear Bit
18

19
//show system_state with dual led between PB2 and PB3
20
#define Show_Status (IO == System_State) ? (Set_Bit(PORTC, PC0)) : (Set_Bit(PORTC, PC1))
21

22
//check if trafo works. If voltage comes back to PIN1 everything is OK
23
#define Check_Output (bit_is_set(PINC,PIN5)) ? (System_State = IO) : (System_State = NIO)
24

25
//exchange if output is active high/low
26
#define time_off   125//125
27
#define time_on      1// 3
28

29
typedef unsigned char u8;
30

31
typedef enum {
32
  IO,            
33
  NIO
34
  } state_t;
35
volatile state_t System_State;
36

37

38
//timer 2 used in CTC Mode
39
void init_timer2(void){
40
  TCCR2A = (1<<WGM21);                                                        //mode 2, CTC Mode
41
  TCCR2B = (1<<CS22) | (1<<CS21) | (1<<CS20);
42
  //prescaler 1024, 8 bit count, 1 count = 8ms, 125 count = 1000ms
43
  OCR2A = time_off;                                                           //interrupt every  second
44
  TIMSK2 = (1<<OCIE2A);                                                       // enable compare interupt
45
}
46

47
ISR(TIMER2_COMPA_vect)
48
{
49
  //Tog_Bit(DDRB,PB1);
50
  if (OCR2A == time_off)                                                     // lange geschlafen, jetzt ausgang aktivieren
51
  {
52
    Set_Bit(PORTB,PB0);
53
    Show_Status;
54
    OCR2A = time_on;                                                         // Einschaltdauer einstellen
55
  }
56
  else
57
  {
58
    Check_Output;                                                            // Überprüfen, ob Ausgangsspannung Trafo
59
//    _delay_ms(1);
60
    Clr_Bit(PORTB, PB0);                                                      // Ausgang wieder aus
61
    Clr_Bit(PORTC, PC0);
62
    Clr_Bit(PORTC, PC1);
63
    OCR2A = time_off;                                                        // Wecker stellen
64
  }
65
}
66

67
void init_io(void){
68
  // init Outputs
69
  Set2Output(DDRB, PB0);                                                     // Transistor für Trafo
70

71
  Set2Output(DDRC, PC0);                                                     // DualLED nach PB2,
72
  Set2Output(DDRC, PC1);                                                     // PC1 = 1 & PC2 = 0 -> grün
73
                                                                             // PC1 = 0 & PC2 = 1 -> rot
74
  Clr_Bit(PORTB, PB0);                                                        // Ausgang wieder aus
75
  Clr_Bit(PORTC, PC0);
76
  Clr_Bit(PORTC, PC1);
77

78
  System_State = IO;
79
}
80

81
void init_sleepmode(void){
82
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
83
}
84

85
/*****************************************************************************/
86
int main(void)
87
{
88
  init_timer2();
89
  init_io();
90
  init_sleepmode();
91

92
  sei();
93

94
  while(1){
95
    sleep_mode();
96
  }
97

98
  return 0;
99

100

101
};

  

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