www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Sleep Mode beim ATMega16


Autor: Timo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Björn Wieck (bwieck)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Owz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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=

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: rene (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt die Moeglichkeit eines externen RTC, zB eines DS1306. Man kann 
auch einen 32K Quarz anhaengen und den die Zeit machen lassen. Eine 
Seite :
http://www.ibrtses.com/embedded/avrpowersave.html

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zu teuer sorry.

gibt es noch eine andere Möglichkeit ausser int oder kompliziert den WDT 
zu verwenden ?

Autor: Werner A. (homebrew)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe bei einem mega168 den internen 32 khz oszi aktiviert und lass 
ihn darüber wieder aufwachen. Dann wird quasi alles schlafen gelegt, nur 
der timer2 läuft weiter.

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mh? wie funktioniert das dann?

ich initialisere mit HS das komplette Programm

Autor: Werner A. (homebrew)
Datum:

Bewertung
0 lesenswert
nicht 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.
/* weckt den Prozessor alle x ms auf und generiert einen kurzen Impuls auf Ausgang PB0
* hier wird mit einem Transistor ein Trafo sekundärseitig angetrieben
*
*/


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>


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

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

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

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

//exchange if output is active high/low
#define time_off   125//125
#define time_on      1// 3

typedef unsigned char u8;

typedef enum {
  IO,            
  NIO
  } state_t;
volatile state_t System_State;


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

ISR(TIMER2_COMPA_vect)
{
  //Tog_Bit(DDRB,PB1);
  if (OCR2A == time_off)                                                     // lange geschlafen, jetzt ausgang aktivieren
  {
    Set_Bit(PORTB,PB0);
    Show_Status;
    OCR2A = time_on;                                                         // Einschaltdauer einstellen
  }
  else
  {
    Check_Output;                                                            // Überprüfen, ob Ausgangsspannung Trafo
//    _delay_ms(1);
    Clr_Bit(PORTB, PB0);                                                      // Ausgang wieder aus
    Clr_Bit(PORTC, PC0);
    Clr_Bit(PORTC, PC1);
    OCR2A = time_off;                                                        // Wecker stellen
  }
}

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

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

  System_State = IO;
}

void init_sleepmode(void){
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
}

/*****************************************************************************/
int main(void)
{
  init_timer2();
  init_io();
  init_sleepmode();

  sei();

  while(1){
    sleep_mode();
  }

  return 0;


};

  

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.