www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik µC in Sleep Modus setzen und wieder aktivieren?


Autor: gunter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
bin ein neueinsteiger in sachen µC, und habe da eine wohl ganz einfache
frage an die heads.
möchte meinen µC sozusagen in sleep modus fahren(wie ich es mache weiss
ich auch noch nicht bis jetzt aber das kommt später) und zwar möchte ich
ein timer programmieren der z.B. nach jeder 60s den µC aktiviert zum
datenübertragung (z.B. temperatur), und nach der übertragung der µC
wieder in sleep modus wechselt bis wieder ein zyklus von 60s vorbei ist
und ein aktueller wert übermittelt wird.

ist das schwer zu realisieren? kenne mich wie gesagt kaum mit µC aus.
wäre über jede hilfe dankbar

mfg
gunter

Autor: Thomas Burkhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

das ist eigentlich nicht schwer zu realisieren, da moderne Controller
Sleepmodi haben und das Aufwecken durch interne (timer) oder externe
Interrupts unterstützen.

Mit welcher µC-Familie willst du denn arbeiten?

Autor: Rainer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also bei den AVRs ist es so dass Interrupts bei (fast?) allen Sleep-Modi
zugelassen werden. Du brauchst dir also darüber nicht den Kopf
zerbrechen ob er die Daten dann auch schickt. Ich bin mir aber nicht
sicher ob er dann auch wieder automatisch in den sleep mode zurück
wechselt. Grundsätzlich wäre es aber ohnehin sinnvoll den sleep()
befehl in die endlosschleife (While(1){ ... }) zu packen. Das
funktioniert sicher. Wenn du genaueres über die Modi wissen möchstest
(wann, wo, was aktiv ist) kann ich dir nur das manual zu herzen legen.
da steht meist alles schön übersichtlich drin.

also schwer ist das sicherlich nicht was du vor hast. wenns wo probleme
gibt einfach melden :)

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Also bei den AVRs ist es so dass Interrupts bei (fast?)
> allen Sleep-Modi zugelassen werden.

Ganz so einfach ist es dann doch nicht. Man muss schon im Datenblatt
nachschauen, ob der zum Aufwachen benötigte Interrupt überhaupt
getriggert werden kann in einem bestimmten sleep-modus.
Zum Beispiel werden die internen Timer recht schnell abgeschaltet,
sodass nur "leichte" Sleep-Modi funktionieren. Mit externem,
asynchronem Timer kann man auch tiefere Sleep-Modi benutzen. Beim
tiefsten sind allerdings IIRC alle Taktquellen abgeschaltet, sodass nur
noch ein Interrupt, der durch einen Interrupt-Pin verursacht wird, zum
Aufwachen führt.

Hängt aber alles vom konkreten AVR ab, man sollte also in jedem Fall im
Datenblatt nachsehen.

Autor: ...HanneS... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und da reicht nichtmal irgendein externer Int, sondern es muss ein
Low-Level-Int aktiviert werden. Denn ein flankengetriggerter Int brauch
den Prozessortakt, der aber im "Tiefschlaf" (Power-down) deaktiviert
ist.
Oder ein spezieller Timer mit externer Taktquelle (Timer2 mit
Uhrenquarz bei einigen Megas).

Wenn also der Sleep-Mode zum Stromsparen dienen soll, dann ist das
nicht ganz so einfach.

Es gibt aber noch die Möglichkeit, den Watchdog-Timer zum Wecken zu
benutzen. Der kommt aber schon nach wenigen Sekunden, 60s dürften damit
(in einem Stück) nicht erreichbar sein.

...

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In deinem Falle geht es um's Stromsparen also ist der "tiefste"
Sleepmodi gerade gut genug. In diesen Modi geht aber nur noch der
Watchdog und dieser ist nicht sehr exakt, was aber nich stören dürfte
bei dir. Deine Main() Procedure muß sofort am Anfang überprüfen ob sie
durch einen Watchdog IQR aufgerufen wurde, das steht in einem Register
des AVR's. Wenn ja inkrementierst du eine globale Variable um den
Betrag an Sekunden die der Watchdog eingestellt wurde und arbeitest
dann Main() normal weiter so daß dort in eine Endlosschleife geendet
wird in der der Sleepmodus wieder aktiviert wird.

Hier mal eine vereinfachte Darstellung:

int Timer = 0;

void Main(void)
{
  _WDR_OFF();
  if MCUCSR & (1 << WDRF)
  {
    Timer += 1;
    if Timer >= 60
    {
       Timer = 0;
       sende Daten
    }
  }
  while (1) do
  {
    MCUCR = (1 << SM1)  | (1 << SE);
    WDTCR = (1 << WDP2) | (1 << WDP1) | (1 << WDE);
    Sleep;
  }
}

an Hand des ATMega8 wird hier der Watchdog mit 1 Sekunde eingestellt
und der Power Down Sleep Mode gewählt. Der Watchdog kann meistens nicht
deine geforderten 60 Sekunden am Stück warten, ca. 2-3 Sekunden sind das
Maximum.

Gruß Hagen

Autor: gunter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
danke  erstmal für eure informativen antworten.
genau wie ihr schon gesagt habt die Sleep-Mode soll zum Stromsparen
dienen.
habe eure antworten schnell überflogen da ich jetzt keine zeit habe
mich damit auseinander zusetzen. werde es aber so schnell wie möglich
nachholen.
habe ehrlich gesagt nicht ganz verstanden wie es geschehen soll, auch
nicht an dem code, kann auch kein assambler, dass wird der grund sein.

also was klar ist das ich eine variable inkrementier bis sie = 60 ist
dann sende ich die daten. so was ihr jetzt mit der while schleife meint
ist mir noch nicht klar. könnt ihr mir die assambler spezifischen code
kommentieren?
z.B.
int Timer = 0;

void Main(void)    'Methode (void)
{
  _WDR_OFF();      '???
  if MCUCSR & (1 << WDRF) '???
  {
    Timer += 1;            'inkrementierung +1
    if Timer >= 60          'wenn>=60, timer =0
    {
       Timer = 0;
       sende Daten          'routine sende Daten aufrufen?
    }
  }
  while (1) do              '???
  {
    MCUCR = (1 << SM1)  | (1 << SE);      '???
    WDTCR = (1 << WDP2) | (1 << WDP1) | (1 << WDE);    '???
    Sleep;    'in sleep versetzen, bekannter befehl?
  }
}


also danke euch, sorry das das alles so wirr ist aber schreibe die
nähsten tage klausuren und mache das parallel, was nicht heissen soll
das es mich nicht beschäftigt, im gegenteil!

gunter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ehe man sich mit dem Stromsparen beschäftigt, sollte man sich erstmal
klarmachen, was man damit erreichen will.

Für den einen ist alles unter 1A sparsam, der andere will im Mittel
möglichst unter 1µA bleiben.

Also mal rüber mit konkreten Zahlen.

Was willst Du ?


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P.S.:

Es werden hier oft die hitzigsten Diskussionen geführt und dann stellt
sich heraus, daß alle Annahmen falsch sind, also alles umsonst war.

Und nur weil sich der Fragesteller keine Gedanken über das Wesentliche
gemacht hat.


Peter

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter, ich gebe dir grundsätzlich Recht, aber für manchen Fragenden ist
der Weg zur richtigen Frage verschlungen :)

@Gunter, als erstesmal ist mein obiger Code ein Pseudocode in C, nicht
Assembler. Dies zeigt schon mal das du dir erstmal eine
Programmiersprache aussuchen musst. Denn deine Frage "ist das schwer
zu realisieren" kann nur beantwortet werden wenn man weis wie hoch
dein Wissens- und Erfahrungsstand ist. Viele Cracks hier würden spontan
antworten "Ja, absolut easy es gibt echt schweres". Viele Anfänger
wiederum verstehen noch nichtmal die Antworten die hier gegeben werden.
Die Cracks würden gutgemeint denoch immer am Anfänger vorbei reden :=)

Dies ist auch der Grund für den Einwurf von Peter, denn um dir die
Lösung deines Problemes leichter zu machen ist es am besten das Problem
ansich einfacher zu gestalten. D.h. ist es überhaupt nötig für deine
Schaltung bis in's letzte mA Strom sparen zu wollen.

Im Normalfalle wirst du mit dem Sleepmodus ca. 20mA sparen können.
Sollte also deine Peripherie schon 1A Ruhestrom verbrauchen so macht es
keinen Sinn mit dem Sleepmodus anzufangen. Du würdest also das Pferd vom
falschen Ende her aufzäumen. Ich glaube das meinte auch Peter. Nachdem
du deine Software soweit programmiert hast das sie im Normalmode alle
60 Sekunden die Daten schickt, und das auch alles funktioniert ist es
wirklich nur eine kleine Softwareänderung um mit dem Stromsparen
anfangen zu können. Wichtig ist dabei nur das du dann aber auch das
nötige Wissen hast und viele sich ganz von selber erklärt.

Wir benötigen also mehr Input von dir.

Nun zu meinem Pseudocode:
Der Watchdog ist normalerweise ein Schutzmechanismus um Software die
durch Programmierfehler sich aufhängt, sprich abnormal weiterläuft,
wieder neu zu starten. Dabei ist der Watchdog ein langsamlaufender
Timer der durch die Software regelmäßig zurückgesetzt werden muß. Falls
dies nun nicht geschiet, das Program also hängt, muß der
Watchdog->Wachhund darauf reagieren. Nun man geht davon aus das der
Reset ein guter Weg ist dies zu tuen. Ein C Program landet nach einem
Reset oder nach dem Einschalten des Processors immer in der Procedure
Main(). Und exakt da springt auch der Watchdog hin wenn er auslösst.

Man kann nun in Main() durch Auswertung verschiedener Flags des
Prozessors unterscheiden ob Main() durch einen normalen Reset oder dem
Watchdog aufgerufen wurde. Genau dies macht die erste IF Abfrage.
Vorher sollte der Watchdog in deinem Falle deaktiviert werden, wasa ich
mit _WDR_OFF() anzeigen wollte. Diese Funktion ist aber unterschiedlich
auf den verschiedenen Compilern und für die genaue Vorgehensweise musst
du unbedingt das Datenblatt lesen.

Nungut, die meisten Main() Proceduren landen auf kurz oder lang in
einer Endlossschleife in der der eigentliche Hauptcode läuft. Genau in
dieser Schleife wird es eine Stelle geben in der der Prozessor in den
Sleepmode geschickt wird. Das wäre im obigen Sourcecode die 3 Zeilen
mit dem Sleep;

Gruß Hagen

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann man sich wirklich darauf verlassen, dass der Watchdog nur main()
aufruft?

Dann müssten doch (durch die avr-libc) sämtliche globalen Variablen,
Ausgabepuffer, random-seed und sonstige interne Variablen der libc neu
initialisiert werden.

Wenn eine globale Variable nur als "int global;" deklariert wurde,
dürfte sie das wohl überstehen. Aber schon ein "int global = 0;"
(semantisch genau dasselbe wie vorhin) dürfte den Inhalt von global bei
einem Watchdogreset leeren.
Das erscheint mir sehr unintuitiv und riskant. Dann doch lieber einen
externen Uhrenquarz zum Aufwecken. Wäre der Stromverbrauch damit so
signifikant höher als beim Watchdog-Wecken?

Oder täusch ich mich (ich kenn die avr libc ja nicht so gut)?

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Kann man sich wirklich darauf verlassen, dass der Watchdog nur main()
aufruft?"

Ja mit klitzekleinem nein :) Auch die Watchdog Routinen im Program
könnte die Ursache sein das der Watchdog auslösst, es wird niemals den
perfekten Schutz geben können. Aber die Wahrscheinlichkeit für solche
Fehler sollte sehr sehr gring sein. Du kannst die also darauf Verlassen
das der Watchdog an Address 0x0000 springt und dort steht der
Sprungbefehl der auch bei einem Reset angesprungen wird.

"Dann müssten doch (durch die avr-libc) sämtliche globalen Variablen,
Ausgabepuffer, random-seed und sonstige interne Variablen der libc neu
initialisiert werden."

Ja, und dies geschiet ja auch, du SIEHST es nur nicht in deinem C
Source. Wenn du mal die *.lst Datei erzeugst, sprich dir den erzeugten
Assemblercode anschaust dann wirst du feststellen das dort besonders
beim WinAVR gcc -> libc noch einiges an Arbeit mit Initalisierungen
usw. erledigt wird. Erst ganz am Ende dieser Arbeit wird Main()
aufgerufen. Vor den Aufruf von Main sind also alle globalen
vorinitialisierten Variablen wieder auf ihren Resetzustand
initialisiert.

Aber Vorsicht dies gilt aber eben nicht für die Register im Prozessor,
denn ein Watchdog IQR ist kein echter Reset. Der Inhalt des SRAMs und
der meisten Register wird also durch den Watchdog nicht zwangsläufig
zurückgesetzt. Dazu muß man das Datenblatt befragen.

Gruß Hagen

Autor: gunter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also,
was alles hinter der hardwaretechnischen sache steckt weiss ich nicht
genau zur zeit und kenne mich da auch nicht mit aus. ich soll die
softwaretechnische  seite lösen.. das sind hier meine ersten shritte in
dieser grossen komplexen welt.
weiss also garnicht mit wieviel A ein µC normal und mit wieviel A ein
µC im Sleep_Modus benötigt, wieviel man an datenmänge speichern bzw
händeln kann.
habe versucht ein datenblatt zu studieren, hab aber nur welche auf
englisch gefunden und da bin ich eine niete.

@Hagen
habe den codes noch nicht ganz begriffen.
was sagt die while (1) do schleife aus?
ich verstehe nur daraus -> WENN 1 dann mach ......
also bis zu while ist klar, der watchdog meldet sich z.B. jede s und
inkrementiert so den timer, wenn der = 60 sind halt die 60 s vorbei und
die daten daten können gesendet werden(man müsste also den µC in der
senden routine wieder aktivieren, geht das auch mit 3 zeilen dann?).
und wie, wodurch weiss mein µC wann er wieder in Sleep modus gehen
soll? das wäre ja z.B. nach einer bestimmten anzahl gesendeter
datenmenge o. einer definierten zeit. macht das die while schleife?
verstehe aber dann nicht sorecht wie? oder kann mann das auch mit einer
condition schleife vergleichen? wo steckt dann aber die info das in
slepp modus geschaltet werden soll.
würde mich auch interessieren was die 3 zeilen genau aussagen, kann man
das irgendwo nachschlagen?

vielen dank für die hilfe.
gunter

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"weiss also garnicht mit wieviel A ein µC normal und mit wieviel A ein
µC im Sleep_Modus benötigt"


Das weiß auch kein anderer.
Dazu müßtest Du Dich erstmal für einen entscheiden.

Hagen hat ja den ATMega8 hellgesehen.


Du weißt aber schon, wie man den benötigten Stromverbrauch ermittelt:

Die Batterie hat xx Ah
Sie soll xx h halten
Andere Schaltungsteile (ohne den µC) benötigen xx mA
Daraus ergibt sich ein mittlerer Stromverbrauch des µC von max xx mA

Dann kann man mal weiter sehen, vorher ist alles nur Geschwafel.


Peter

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja und das ist das Problem :) Fragen, egal welche, sind niemals
verkehrt oder dumm, es sei denn aus einer Frage werden lawinenartig
immer mehr Fragen.


"was alles hinter der hardwaretechnischen sache steckt weiss ich
nicht
genau zur zeit und kenne mich da auch nicht mit aus. ich soll die
softwaretechnische  seite lösen"

Du willst auf MCU's entwickeln da gehört grundlegendes Wissen der
Hardware dazu, es geht nicht ohne. Auf PC's mit .NET könnte ich
verstehen das ein Softwareentwickler ganz ohne Hardwarekenntnisse
auskommen kann, aber auf MCU ?? das geht nicht.
Und damit du die HW kennst MUSST du auch english können, das brauchst
du in der Programmierung wie auch zum Lesen der Datenblätter, es geht
nicht ohne. Du kannst dir eine gewissen Zeit lang abhelfen indem du die
Online Translatoren benutzt, hm aber wie lange ?


"habe den codes noch nicht ganz begriffen.
was sagt die while (1) do schleife aus?"

Das diese Schleife eine Endloss-Schleife ist, sie wird also nur durch
einen Reset/Watchdog/Stromausschalten beendet, und höchsten noch durch
Interrupts unterbrochen. Alles was innerhalb dieser Schleife ist wird
normalerweise ständig wiederholt ausgeführt. Allerdings steht in meinem
Pseudocode (der den ATmega8 einfachmal als hyptothetische MCU angenommen
hat:) ein Sleep; Vor dem Sleep wird aber noch der WatchDog und der
Sleepmode ausgewählt. Im Falle eines ATMega8 wird der Watchdog auf 1
Sekunde gesetzt und der Sleepmode auf "Power down". Danach wird die
MCU in den Sleep Modus versetzt. Alles, selbst der Quarz wird
angehalten und im Normalfalle verbraucht der AVR dann nur wenige µA.
Aus diesem Modus kann er nur durch wenige Interruptsourcen wieder
aufgeweckt werden, eben ua. mit dem WatchDog.
Wenn nun 1 Sekunde vergangen ist und der WatchDog Timer abgelaufen ist
wird die MCU wieder "aufgeweckt" und beginnt bei Main() von vorne.
Deshalb die erste IF Abfrage die nämlich überprüft ob der WatchDog den
AVR aufgeweckt hat. Wenn ja wird der Timer erhöht und bei >= 60
Sekunden sendest du deine Daten. Du musst dort nicht mehr den AVR
aktivieren oder sonstwas, denn der AVR IST dann schon längst aktiviert,
heist nicht mehr im Power Down Sleep Mode. Nach senden deiner Daten
gehts ganz normal mit der While(1) do Schleife weiter so als wäre nicht
geschehen. Den Rest der Logik kannste dir nun selber denken.

"und wie, wodurch weiss mein µC wann er wieder in Sleep modus gehen
soll? das wäre ja z.B. nach einer bestimmten anzahl gesendeter
datenmenge o. einer definierten zeit. macht das die while schleife?
verstehe aber dann nicht sorecht wie? oder kann mann das auch mit einer
condition schleife vergleichen? wo steckt dann aber die info das in
slepp modus geschaltet werden soll."

Ja, in meinem Pseudocode bin ich nur aus das WESENTLICHE eingegangen.
Der AVR würde eigentlich immer und sofort in den Sleep Mode gehen und
nur alle 60 Sekunden die "Daten Senden" Routine aufrufen. Willst du
dies anders haben muß natürlich in der While do Schleife der Sleep
Modus samt WatchDog anders konfiguriert werden.

"würde mich auch interessieren was die 3 zeilen genau aussagen, kann
man das irgendwo nachschlagen?"

Ja, eben im Datenblatt das in englisch ist. Daran geht kein Weg
vorbei.

So, nun fange an an dir zu arbeiten, lerne C oder die
Programmiersprache die du benutzen willst. Frage deine HW-Entwickler
auf was für Hardware du entwickeln sollst, ohne diese Wissen kannst die
für MCU keine Software programmieren.

Ich sehe nämlich die Gefahr das du hier im Forum immer weniger
Antworten erhälst da eventuell nicht jeder so geduldig ist wie ich zb.
Ich weis das man als Anfänger nach einer beantworteten Frage immer mehr
Fragen auftauchen sieht und so ein schieres Gewirr von Fragen entsteht.
Du kannst leider nicht verlangen das nun andere ihre Zeit opfern um auf
ALLE diese Fragen einzugehen. Du musst also uns entgegenkommen und mit
konkreten Fragen aufwarten ansonsten wird keiner sich die Zeit nehmen
wollen darauf zu antworten (es werden nach jeder Antwort immer mehr
Fragen :)
Und da dies hier ein Fachspezifisches Forum ist musst du dich auch
selber in die fachspezifische Materie einarbeiten -> ergo: englisch,
Programmiersprache, Datenblätter und ein bischen Elektronik.

Gruß Hagen

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Peter
"Dann kann man mal weiter sehen, vorher ist alles nur Geschwafel."

Ja das ist im Grunde richtig. Aber wie soll ein Anfänger einen groben
Überblick bekommen, zb. über die Randerfordernisse wie Englisch,
Programmiersprachen usw. wenn nicht wir diejenigen sind die seine
Fragen versuchen zu beantworten ?

Vor nicht allzulanger Zeit war und bin auch ich Anfänger gewesen. Ok,
ich hatte es viel leichter da ich eh schon seit 15 Jahren programmiere
und englisch kann. Aber grundsätzlich hatte ich auch tausende Fragen
und nach jeder wurden es mehr. Und ich weis nicht wie es dir ergangen
ist, aber ich meinerseits wollte möglichst in 5 Minuten alles auf
einmal wissen :=)

Konstruktiv gesehen kommen bei solchen Threads keine fertigen HW/SW
Lösungen raus, das dürfte klar sein. Aber man kann lernen was alles an
Wissen benötigt wird und wo man wie am besten anfangen muß.

Gruß Hagen

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hagen,

man muß vor allem das systematische Herangehen lernen.

Es macht nunmal keinen Sinn sich Gedanken über die Farbe der Tapete zu
machen, wenn man sich noch nicht mal über das Fundament im klaren ist.

Und solange bleiben Diskussionen über die Farbe der Tapete eben nur
Geschwafel.


Also immer einen Schritt nach dem anderen.

Und in diesem Fall ist der allererste Schritt eben das Aufstellen einer
Energiebilanz.


Peter

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:) Peter, ich bin da absolut deiner Meinung, nur mit einem kleinen
Unterschied: Wie soll ein Anfänger lernen was systematisches Vorgehen
bedeutet wenn es ihm keiner sagt ? Deshalb versuche ich eben auch auf
solche Fragen zu antworten, eben weil ich selber Anfänger war bzw. noch
bin.

Weist du, in fast allen Foren wird sich über unklare Fragen beschwert
und immer wieder auf Datenblätter oder Forenregeln verwiesen, mehr
nicht. Aber wie soll ein Anfänger ein Gefühl für gute Fragen erlernen
wenn man es ihm nicht beibringt oder zumindestens erstmal eine Antwort
leifert und er dann feststellen kann das er vorerst wichtigere Dinge
lernen muß ?

Mir persönlich ergeht es immer so mit Fragen zur Elektronik. Öfters
sind es Fragen die jeder Elektroniker als Grundlagenwissen abtut und
mit RTFM beantwortet. Es ist aber so daß ich zb, auf der einen Seite
ein großes Fachwissen zb. in der Programmierung habe auf der anderen
Seite noch nichtmal exakt weis wie ein MOSFET oder OPAMP im Detail
funktioniert. Sogesehen ein Fach-idiot-experte, und dem helfen dann
RTFM-Antworten überhaupt nicht weiter, denn ich verstehe die
Datenblätter einfach nicht. Einfach eine fertige Sache nachbauen will
ich aber auch nicht und einen Privatlehrer kann ich mir nicht leisten.
Also bleibt mir nur eines übrig: ich stelle eventuell saublöde Fragen
in einem Forum :)

Gruß Hagen

Autor: gunter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
moin,
so ist es hagen, du hast recht, sprichst mir von der seele!
danke für deine tips. mache mich gleich auf die suche nach einen guten
c tutorial. falls ihr ein guten link habt bitte her damit.

danke erstmal für die tips und infos werde mich melden wenn ich mehr
weiss.
mfg
gunter

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich muss mal diesen alten Beitrag wieder raus holen.
Ich will meinen Atmega8 schlafen legen und per Watchdog wecken.
Hier der Code:

#include <lcd.c>
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/sleep.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "avr/wdt.h"
#define F_CPU   8000000



volatile int loop = 0;


void pause (void);

int main(void)
{
  lcd_init();

  lcd_print(0,0,"Start ");
  DDRB |= (1 << PINB0); ///led
  pause();
  lcd_clear();

  set_sleep_mode(SLEEP_MODE_IDLE);
  //set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  //////////////////////////////////////////////////////////
  wdt_disable();


  if (MCUCSR & (1<<WDRF)){

  loop++;
  lcd_print(0,0," %i      ",loop);
  if (loop == 5){
  PORTB |= (1<<PINB0);
  pause();
  PORTB &=~ (1<<PINB0);
  pause();
  loop = 0;    }
               }





  for(;;){
  MCUCSR &=~(1<<WDRF);
  wdt_enable(WDTO_2S) ;
  sleep_mode();
      }

}

void pause (void){
  for (char s=0;s<15;s++){
  _delay_ms(10);}

        }
Er springt auch schön immer wieder in die main. Das sehe ich weil auf 
dem LCD wieder start nach ca. 2sec. steht. Nur inkremiert er nicht die 
Variable loop. Die springt einmal auf eins und da bleibt sie, sodas 
meine LED gar nicht angesteuert werden???

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Sleep Mode

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Falk Brunner,
ich habe versucht es mittels deines Links, nach zu vollziehen.
Wenn ich das richtig verstehe, springt er nach meinem Watchdog reset, 
dirckt zur main. as heist meine Variable loop müßte doch noch bestehen?! 
Also auch hoch gezählt werden.
Frank

Autor: Nico (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, der Watchdog führt einen kompletten Reset aus und der µC ist im 
selben Zustand wie nach einem normalen Reset. In einem C-Programm läuft 
er also mit der ganzen Initialisierung los und dann erst startet deine 
main.

Am einfachsten geht es wenn du einen Watchdog-Interrupt einrichtest, den 
Watchdog auf Interrupt betrieb stellst und das was du im normalfall 
ausführen willst in eine schleife packst, an deren Ende der µC in den 
sleep-mode versetzt wird. Der Interrupt weckt den µC dann wieder auf und 
deine Schleife läuft weiter, dabei bleiben dann natürlich alle Daten 
erhalten. Für längere Wartezeiten als der Watchdog zulässt kannst du 
dann einfach einen Counter mit einbauen.

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.