Forum: Mikrocontroller und Digitale Elektronik Die PowerDown-Tücke!


von Richard Spatschinski (Gast)


Angehängte Dateien:

Lesenswert?

Hallo alle miteinander,

seit einiger Zeit plage ich mich mit der (zumindest scheinbaren)
Instabilität des CPU-Zustandes der ATmega8 im PowerDown-Modus.

Symptome: Nach einer LÄNGERER (mehrere Stunden langer) PowerDown-Phase
wacht der µC entweder gar nicht auf, oder der PC springt zu einer
zufälligen Adresse im Programspeicher, was natürlich einen kompletten
Zusammenbruch des logischen Programmablaufes nach sich zieht.
Als sekundäre Ursache ziehe ich mehrere Möglichkeiten in Betracht:
1.: Die Inhalte der Register überleben den "Winterschlaf" nicht
2.: Die SRAM bekommt Gedächtnisschwund (zu wenig Strom?)
3.: Es ereignet sich während der Aufwachphase ein teilweiser Reset mit
einem undefiniertem Post-Reset-Zustand

Wie kann und darf es aber dazu kommen?!
Ich hoffe, jemand weiss' es!
Falls es jemandem nützt, füge ich meine PowerDown-ISR als Anhang hinzu.

von Frank Wolf (Gast)


Lesenswert?

lies mal:
http://www.mikrocontroller.net/tutorial/interrupts

dann findest du schnell die Fehler
(das erste reti z.B.)...

Wenn du noch strom sparen willst empfehle ich:
http://www.mikrocontroller.net/forum/read-1-176066.html#new
ich hatte da so meine probleme ;)

GreetX, [int]

von Richard Spatschinski (Gast)


Lesenswert?

Hallo Frank,

vielen Dank für die Links!

Das erste "reti" ist korrekt, da meine PowerDown-Routine eine ISR ist
und wird im Falle eines Input-Compare-Interrupts ausgeführt.

Wie gesagt: das Programm funktioniert einwandfrei (auch das
"aufwachen"). Das Rätsel liegt darin, das die Probleme NUR NACH
LÄNGEREM PowerDown-Zustand auftreten (ab ca. 10 Std).
µC - Wechsel bringt auch nichts!

Es ist ein kommerzielles Programm und ich werde bald wannsinnig!!!

Ich habe zwar das Problem umgangen, in dem ich alles Wichtige ins
EEPROM rette, aber ich stehe nicht auf diese Ausweichmanöver!

mfg Richard

von TAS (Gast)


Lesenswert?

Hi,

hast Du schon mal an Brown-out gedacht, oder liegt Deine
Versorgungsspannung immer stabil an?

von Richard Spatschinski (Gast)


Lesenswert?

Hallo TAS,

der Brown-Out ist auf 2,7V eingestellt, die Spannungsversorgung liegt
bei exakt 4,1V (vier Mikro-Akkus minus Dioden-Schleusenspannung).
Das Problem trat aber auch bei 5,3V auf.

Könnte es evtl. an der Beschaltung liegen (Abblockkondensator etc., was
macht er überhaupt)?

Ich bin nämlich kein Elektroniker, sondern ein Programmierer.
Das kleine Gerät ist aber so einfach aufgebaut (LCD-Display, 6 Tasten
und ein Paar LED's, das ich es selber machen durfte).

HOLT MICH HIER RAAAAAUUUUUSSSSS!!!!!

von Hauke Radtki (Gast)


Lesenswert?

Abblock kondensator is dazu da um spannungstiefpässe zu filtern ... aber
bei nem batteriegerät hat das nich sooo viel sinn (die batteriespannung
hat ja keine lücken)

von ---- (Gast)


Lesenswert?

Weitere Puzzlesteinchen:
Deine Elektronik ist auch nicht mit einem PC verbunden (z.B. RS232) und
deine Software stürzt sauber beim Ausschalten des PCs ab? Und du merkst
das erst später...?

Variablen- oder Stacküberlauf erst nach Stunden?

----, (QuadDash).

von ---- (Gast)


Lesenswert?

> Abblock kondensator is dazu da um spannungstiefpässe zu filtern
Was sind denn Spannungstiefpässe?
Ein Abblockkondensator ist dazu da, um hochfrequente
Spannungsschwankungen abzublocken, die z.B. bei schnellschaltenden
Digitalsignalen entstehen. Oder um z.B. von außen eingekoppelte
hochfrequente Störungen zu filtern. Und die gibt's auch bei
batteriebetriebenen Geräten.
Abblockkondensator != Stützkondensator. Und selbst der macht Sinn bei
'größeren' Lastschwankungen...

----, (QuadDash).

von Hauke Radtki (Gast)


Lesenswert?

stimmt ... hast recht ... ihr könnt mich killen ;-P

von Richard Spatschinski (Gast)


Lesenswert?

Hallo ----,

"...Deine Elektronik ist auch nicht mit einem PC verbunden (z.B.
RS232) und
deine Software stürzt sauber beim Ausschalten des PCs ab?"

->Es ist ein kleines portables Gerät in einem Gehäuse und ist NICHT
mit'm PC verbunden!



"...Variablen- oder Stacküberlauf erst nach Stunden?"

-> Hallo, es ist PowerDOWN-Modus! Da läuft NICHTS mehr!

Trotzdem danke, dein Beitrag zum Abblockkondensator war lehrreich!

von Hauke Radtki (Gast)


Lesenswert?

vielleicht irgend ein defektes bauteil, dass die batterien auffrisst?
schon ma geguckt, ob die stromaufnahme normal ist?

von Hagen (Gast)


Lesenswert?

Füge mal hinter dem Sleep mehrere NOP's ein.
Als zweites könnte es helfen wenn du eine System-Status-CRC Funktion
hättest. Diese berechnet eine 16 Bit Prüfsumme über alle Register und
SRAM Inhalte. Du berrechnest eine vor deinem Sleep und speicherst sie.
Nach dem Sleep nochmal beerechnen und mit der gespeicherten
vergleichen. So könntest du wenigstens herrausfinden ob tatsächlich
Informationen verloren gehen.

Gruß Hagen

von Richard Spatschinski (Gast)


Lesenswert?

Vielen Dank Hagen, werd' ich beides versuchen!

von ...HanneS... (Gast)


Lesenswert?

Ich bin ja nun kein "Programmierer"...

Aber:

- In deinem Beispiel sehe ich keine Sicherung des SREG.
- In einer ISR würd' ich den AVR nicht schlafen schicken, dies mach'
  ich immer am Ende der Main-Loop, dann, wenn alle Jobs erledigt sind.

Deine ISR kann ja vorher den Sleepmode festlegen. Standard wäre Idle,
wenn die Tiefschlafbedingung auftritt (InputCapture), wird auf
PowerDown umgeschaltet.

Vielleicht bin ich aber auch nur zu blöd, den Gedanken eines
Programmierers zu folgen.

Gruß...
...HanneS...

von Hagen (Gast)


Lesenswert?

Jay, wenn ich das richtig verstanden habe ist es keine richtige ISR,
bzw. er nutzt sie als normale Funktion. Der Trick ist das er mit CLI
die IRQ's sperrt und erst bei der Rückkehr der Funktion implizit im
RETI des I Flag wieder setzen möchte.

Gruß Hagen

von Benedikt17 (Gast)


Lesenswert?

"...- In deinem Beispiel sehe ich keine Sicherung des SREG."
-> die Sicherung des SR wird nict benötigt.


-"... In einer ISR würd' ich den AVR nicht schlafen schicken..."
-> dann erkrär' mir bitte, wieso ich es so machen soll, wie du?!
Diese ISR ist halt das Schlafzimmer, und wen juckt's?


>"...Vielleicht bin ich aber auch nur zu blöd, den Gedanken eines
Programmierers zu folgen."
-> Was soll hier der Kindergarten?

von Thomas (Gast)


Lesenswert?

Geht die MCU wirklich in den Powerdown-Modus ?

Beim setzen des SE-Bits löscht Du gleichzeitig die SM- und ISC-Bits im
MCUCR.

Gruß Thomas

von Thomas (Gast)


Lesenswert?

Noch was

Wenn die MCU durch das Löschen der SM-Bits in den Idle- anstatt dem
PowerDown-Modus geht läuft der Timer weiter und jeder Compare-Match
weckt die MCU auf und startet die ISR erneut ohne das die vorherige
beendet wurde. Das passiert alle 65536 Timerzyklen bis irgendwann ein
anderer Interrupt auftritt. Dabei wird der verfügbare Platz auf dem
Stack immer kleiner.

Thomas

von Michael (Gast)


Lesenswert?

In der Codesammlung befindet sich eine 'geniale' Tastenentprellung.
Hast Du diese vielleicht im Programm eingebunden und eine Taste ist
gedrückt (o.ä.) ?

von peter dannegger (Gast)


Lesenswert?

Wenn ich das richtig verstanden hab, wird der Aufwachinterrupt noch
ausgeführt und erst danach kracht es.

Dann mach doch einfach innerhalb des Interrupts einen kompletten SRAM-,
Register- und IO-Dump auf die UART (direkt inline, ohne
Unterfunktionen).

Dann siehst Du ja, wo es kracht.

Ich fülle den SRAM + Register nach dem Reset zum Debuggen mit 0x77, da
sieht man dann schön im Dump, wo noch was frei ist.

Es sollte immer ein großer Bereich von 0x77 zu sehen sein, wo noch
freier Speicher gewesen ist. Bei 1k SRAM würde ich 16 Byte Reserve als
absolutes Minimum ansehen.


Peter

von Hagen (Gast)


Lesenswert?

Richard ???

Deine Methode mit der ISR verursacht ziemlich Wirbel, du solltest
nochmal genauer erklären ob tatsächlich inerhalb der ISR in den Power
Down Mode gegeangen wird. Wenn ja dann ist dies meiner Meinung nach
falsch, denn du lässt ja mit SEI die IQR's wieder zu und das in einer
ISR. Sowas führt immer zu Problemen.

Also: definiere ein globales Flag in einem Register oder so und setze
dies innerhalb deiner ISR's auf TRUE wenn in den PowerDown Modus
gegangen werden soll. Nun baust du deine Main Loop um. Dies wird ja
eine Endlossschleife sein und in der fragst du diese Flag ab. Wenn TRUE
auf FALSE setzen und in den Power Down Modus wechseln. So wird es auf
keine Fälle zu Problemen mit den ISR's kommen.

Gruß Hagen

von peter dannegger (Gast)


Lesenswert?

Ich würde einfach mal zwischen sleep und cli noch 10 nops einfügen.

Glaube irgendwo mal gelesen zu haben, daß direkt nach dem sleep Mist
passieren kann.


Peter

von Hagen (Gast)


Lesenswert?

Hi Peter,

sowas habe ich auch schon irgendwo gelesen (glaube sogar in einer AN
von Atmel) und deshalb schlug ich das gleiche ja schon par Postings
weiter oben vor.

Denoch, wie den meisten anderen hier kommt mir auch die Methode mit der
ISR spanisch vor. Leider hat sich Richard in diesem Punkt nicht
eindeutig geäußert. Ist es nun eine ISR oder ist es eine normale
Funktion die nur einen programmirtechnischen Trick anwendet um auf
clevere Art und Weise das I Flag zu restaurieren.

Sollte es eine ISR sein so muß der Sleep und das SEI/CLI da raus und in
die Main Loop. Davon abgesehen wäre diese ISR sehr wahrscheinlich durch
die vielen Unterfunktionsaufrufe auch noch ziemlich langsam. Sollte es
eine normale Funktion sein so gehe ich davon aus das diese aus der Main
Loop herraus aufgerufen wurde und alles wäre zumindestens
Softwaretechnisch paletti.

Ich jedenfalls habe von so einem Power Down Problem das erste mal
gehört und dies legt den Verdacht nahe das es ein Softwareproblem sein
muß.

Gruß Hagen

von ...HanneS... (Gast)


Lesenswert?

Es ist eine ISR:
(http://www.mikrocontroller.net/forum/read-1-176240.html#176515)

Zitat:
Das erste "reti" ist korrekt, da meine PowerDown-Routine eine ISR
ist
und wird im Falle eines Input-Compare-Interrupts ausgeführt.

...

von Thomas (Gast)


Lesenswert?

Hallo

Ich vermute es ist eine echte ISR die bei einem Compare Match
eines Timers ausgelöst wird. Sinn der Sache könnte sein den AVR
nach einer bestimmten Leerlaufzeit in den Powerdown zu schicken.

Wenn die MCU in den Powerdown geht laufen die Timer nicht weiter
und es kann trotz freigegebener Int's nicht zu einem erneuten
Compare Match Interrupt (während die MCU durch SLEEP noch in der
ISR ist) kommen.

Meiner Meinung nach geht die MCU aber nur in den Idle-Mode und
da laufen die Timer weiter. Durch das wiederholte Ausführen der
ISR ohne das die vorherige ISR beendet wurde wird der Stack immer
kleiner bis halt nichts mehr da ist.

Gruß Thomas

von Richard Spatschinski (Gast)


Angehängte Dateien:

Lesenswert?

Vielen Dank für Eure Anregungen!
Ich habe das Problem lokalisiert und beseitigt.
Woran es lag?
Daran, woran wir alle nicht gedacht haben und nicht denken konnten:
es war ein (laut Datenblatt nicht zugelassener) TCNT-Interrupt (s.
Programm im Anhang)!

ACHTUNG: es ist ein Irrglaube, dass im PowerDown-Zustand die Timer
automatisch angehalten werden!
Jede hierdurch möglich werdende IRQ (Überlauf, OC etc.) reisst den µC
sofort aus seinem Schlaf!
Das, obwohl im Datenblatt folgendes steht (Zitat):
"Only an External Reset, a Watchdog Reset, a Brown-out Reset, a
Two-wire Serial Interface address match interrupt, or an external level
interrupt on INT0 or INT1, can wake up the MCU."

In meinem Fall wurde die PowerDown-Routine durch eine immer wieder
während des "Schlafes" aufgetretene OutputCompareMatch-Exception so
oft aufs neue aufgerufen, bis der arme Kumpel Stack es nicht mehr
gepackt hatte. Das "Spinnen" des Programmes nach einigen Stunden
erkläre ich mir mit dem Überschreiben der SRAM-Daten durch den SP.

P.S.: An alle, die an Idle gedacht haben: Meine Routine im allerersten
Thread ist nicht die Originalroutine und führt tatsächlich zum Idle.
Die Probleme tauchten allerdings mit dem "ECHTEN" PowerDown auf
(siehe Anhang).

von OldBug (Gast)


Lesenswert?

Hättest Du den µC nicht innerhalb der ISR schlafen gelegt, hätte das
Teil wenigstens nicht angefangen zu spinnen...

Aber...lassen wir das ;-)

von peter dannegger (Gast)


Lesenswert?

"Meine Routine im allerersten Thread ist nicht die
Originalroutine..."


Ich wundere mich immer wieder, wie Leute Hilfe erwarten OHNE DEN
KOMPLETTEN FEHLERHAFTEN CODE zu posten !


Runterbrechen auf das minimal notwendige ist natürlich erwünscht, aber
dann unbedingt TESTEN OB DER FEHLER IMMER NOCH AUFTRITT !


HELLSEHEN KANN HIER KEINER !


Hier weiß also immer noch keiner, welchen Power-Down Du wirklich
genommen hast und es gibt ja den, der T2 weiter laufen läßt. Auch
könnte ein Interrupt genau zwischen SEI und SLEEP zuschlagen.


Und OldBug hat ja sowas von Recht. Interrupts in ISRs freizugeben
sollte nur der tun, der auch ganz genau weiß, was er da macht. Das
vorherige Sperren ALLER nicht benötigten Interrupts ist quasi Pflicht.


Peter

von Thomas (Gast)


Lesenswert?

Ein Interrupt zwischen SEI und SLEEP kann eigentlich nicht auftreten.
Der auf SEI folgende Befehl wird vor jedem anstehenden Interrupt
ausgeführt.

Gruß Thomas

von Richard Spatschinski (Gast)


Lesenswert?

@Peter
1.: Die 2. gepostete Routine und der komplette verbale Bezug auf die
erste Routine ist relevant (der Missverständnis tut mir Leid).

2.: Nicht nur der T2, sondern ALLE 3(!) Timer des mega8 laufen im
PowerDown weiter (entgegen den Datenblatt-Angaben, s. bitte Zitat in
meinem letztes Posting). Hast Du eigentlich meine zuletzt gepostete
Routine (ein lauffähiges Programm) zumindest im Simulator ablaufen
lassen, bevor Du geantwortet hast?

3.: Zitat aus dem Datenblatt Nr.2: "...the instruction following SEI
will be executed before any pending interrupts...".
Deswegen eine berechtigte Frage: könntest Du bitte genauer erklären,
was daran nicht I.O. sein soll, wenn ich mein Gerät INNERHALB einer ISR
in den PowerDown-Zustand versetze?!

mfg Richard

von Hagen (Gast)


Lesenswert?

>was daran nicht I.O. sein soll, wenn ich mein Gerät INNERHALB einer
>ISR in den PowerDown-Zustand versetze?!

Du kannst das alles machen nur verkomplizierst du damit einiges. Damit
die MCU aus dem Sleep erwachen kann bedarf es eines Interrupts. Ergo
muß vor dem Sleep die IRQ's aktiviert sein. Da du aber in einer ISR
den Sleep benutzen willst und in einer ISR die Interrupts standardmäßig
deaktiviert sind musst du eben SEI aufrufen. Aber in diesem Moment
bekommst du "Probleme" mit der IQR Logik der AVR's, denn diese sind
im Grunde nur darauf ausgelegt zu einem Zeitpunkt immer nur einen IQR
ausführen zu können. Man kann das zwar alles so wie du machen nur gibt
es viel einfachere und sichere Wege zum gleichen Ziel zu gelangen.
Statt dem Sleep in der ISR wird dort einfach ein globales Flag gesetzt.
Dieses Flag wird nun in der eh vorhandenen Main Loop ausgwertet und dort
dann in den Sleep Modus gegangen. Mit dieser Methode kann es zu
keinerlei Seiteneffekten mit den ISR's kommen und alles funktioniert
sauber. Es geht hier also NICHT um die Auschöpfung aller Möglichkeiten
sondern im Grunde eher um eine deffensive und sichere Art und Weise in
der Programmierung und im Programmierstil allgemein.

Gruß Hagen

von Hagen (Gast)


Lesenswert?

Achso: das problem mit SEI vor dem SLEEP ist nicht nur die eventuell
eingebaute Zeitspanne zwischen SEI und SLEEP, falls zb. NOP's drinnen
sind, sondern entsteht auch dann bei der Aktivierung der MCU aus dem
PowerDown Mode, sprich die Befehle nach dem Sleep.
Wie ich oben schonmal angedeutet hatte habe ich irgendwo schon mal in
einer AN gelesen das man nach einem Sleep einige NOP's reinbauen
sollte, um Anlaufprobleme zu umgehen auf einigen AVR's. Nun in einer
ISR müsstest du nach dem SLEEP sofort wieder CLI aufrufen, aber selbst
daas hilft NICHT. Denn angenommen das SLEEP hast du in deiner Compare
Match ISR drinnen und die MCU wurde aber durch einen Low Level IQR an
INT0 aufgeweckt. Dann verzweigt die MCU erstmal in deine ISR zum INT0
und arbeitet erst danach die Befehle nach dem Sleep ab. In der
Zwischenzeit könnte aber schon wieder der nächste Compare Match IQR
eingetroffen sein und ergo arbeitet die MCU einen Code VOR deinem Sleep
erneut ab, geht in den Power Down, wird durch INT0 geweckt, bekommt in
der Zwischenzeit einen OCR1A IQR, geht in den Sleep, wird durch INT0
geweckt, in der Zwischenzeit ein OCR1A IQR, geht in den Sleep usw. usw.
usw. und usw. wenn da nicht der Stack zu Ende wäre.

Also: nimm den Sleep + SEI + CLI aus deinen ISR's raus, baue das in
deine Main Loop rein und benutze ein globales Flag zum Einschalten des
PowerDown Modus. Und schon haste diesen ganzen Mist nicht mehr zu
beachten.

Gruß Hagen

von Thomas (Gast)


Lesenswert?

@Hagen

So kompliziert wie das scheint ist das gar nicht. Man braucht doch
nur das Maskierungs-Bit des Compare-Interrupts vor dem SEI zu löschen
und erst nach dem CLI wieder zu setzen. Ich benutze auch ISR's die
die Int's wieder freigeben, bis jetzt hatte ich noch nie Probleme.

Thomas

von OldBug (Gast)


Lesenswert?

Wenn man weiss, was man macht...

Ich frage mich allerdings, warum man immer "von hinten durch die Brust
ins Auge" schiessen muss, wenn es auch wesentlich einfacher, sicherer
und übersichtlicher geht.

Taucht mal ein Fehler (hier schon in der Entwicklungsphase!) auf, schon
sucht man die Nadel im Heuhaufen! Warum?

Es wäre nie zu einem Ausfall des Systems aufgrund dieses Fehlers
gekommen, wenn Richard den µC nicht in der ISR sondern in der
Hauptschleife eingeleitet hätte. Da wäre es höchstens zu erhöhtem
Stromverbrauch gekommen!

Es gibt also kein einziges Argument für die ISR-Sleep-Variante...

von peter dannegger (Gast)


Lesenswert?

Du sagst ja, daß Dein Stack übergelaufen ist und das kann nur bei einer
Rekursion passieren, d.h. der Interrupt, der SEI ausführt, hat sich
immer wieder selbst aufgerufen.

Wenn man sich also nicht absolut sicher ist, daß er nicht noch einmal
auftritt bevor man ihn wieder verlassen hat und man ihn trotzdem nicht
gesperrt hat, dann sollte man die Finger von solchen heißen Eisen
lassen.

Deshalb ja die große Betonung auf "man muß dann genau wissen, was man
tut".

Deshalb versuche auch ich wie OldBug, solche hochriskanten
Programmiermanöver generell zu vermeiden und erst recht, wenn sie
überhaupt nicht nötig sind.


Peter


P.S.:
Es kann auch gut sein, daß ein unbalanciertes PUSH/POP oder CALL/RET
den Stackfehler verursacht und Du den eigentlichen Fehler noch garnicht
gefunden hast.

Deshalb ja mein Hinweis: "Man sollte immer einen kompletten
lauffähigen Code schicken, den man getestet hat, daß er den Fehler auch
noch enthält."

von Richard Spatschinski (Gast)


Lesenswert?

Vielen Dank an alle!

Vielleicht wäre es wirklich sicherer, künftig den SLEEP-Befahl NICHT in
einer ISR aufzurufen.

@Peter:
Der Fehler lag an den Timer-Interrupts, da sie im PowerDown weiter
liefen und den µC aufweckten (laut Datenblatt unmöglich!), um danach
die PowerDown-ISR erneut aufzurufen, wobei SP logischerweise jedesmal
doppelt dekrementiert wurde und überlief).
Der Fehler tritt nicht mehr auf, nach dem ich die Timer vor dem
"Einschläfern" abstelle.

Vielen Dank, es hat sich erledigt!

mfg Richard

P.S.: Sind eigentlich auch andere Unstimmigkeiten in den Datenblättern
von Atmel bekannt?

von peter dannegger (Gast)


Lesenswert?

@Richard,

"Der Fehler lag an den Timer-Interrupts, da sie im PowerDown weiter
liefen und den µC aufweckten (laut Datenblatt unmöglich!)"


Das ist ja nur eine Behauptung von Dir, die hier keiner überprüfen
kann, da keiner Deinen Code kennt oder eine abgespeckte Version mit dem
Fehlerbild.

Wenn man Behauptungen aufstellt, dann sollte man sie auch mit einem
Beispiel untermauern können.

Ich bin da immer sehr vorsichtig, etwas zu behaupten, was nicht dem
Datenblatt entspricht ohne das ich es überprüft habe.

Daß ein Fehler nicht mehr bemerkt wird, wenn man etwas am Code ändert,
heißt noch lange nicht, daß man wirklich die fehlerhafte Stelle
gefunden hat.


Peter

von Richard Spatschinski (Gast)


Angehängte Dateien:

Lesenswert?

@Peter:
>"...Wenn man Behauptungen aufstellt, dann sollte man sie auch mit
einem Beispiel untermauern können."

Hallo Peter,
im Anhang befindet sich ein Lauffähiges Programm, das ich weiter oben
schon mal (leider unglücklich) gepostet hatte. Lass es doch bitte mal
ablaufen (z.B. im Simulator), bevor Du in Deinem nächsten Thread mich
wieder angreifst!
Das Programm untermauert meine Behauptung, dass bei einem AVR (getestet
wurden ATmega8 und ATmega16) alle Timer im PowerDown-Modus weiterlaufen
und imstande sind, alle einschlägigen Interrupts zu erzeugen und den
Controller hierdurch zu wecken (nachgewiesen bei Overflow- und
OutputCompareMatch-Ereignissen).

Beschreibung:
1.: Beim TC0-Überlauf wird der PowerDown-Modus aktiviert.
Alle drei Timer laufen dabei munter weiter.
2.: Nach 255 Zyklen geschieht ein erneuter TC0-Überlauf, der µC wacht
auf, führt die PowerDown-ISR erneut aus und schläft wieder ein (der SP
wird hierdurch natürlich 2x dekrementiert!)
3.: Dann, beim TC1-OC-Interrupt, wird eine andere ISR ausgeführt, der
AVR wacht erneut auf und kehrt zurück in die Main Loop.

Erbitte Kommentare!

mfg Richard

von peter dannegger (Gast)


Lesenswert?

Ich wüßte nicht, wo ich Dich angegriffen hätte.

Allerdings denke ich, daß zu einem Forum nicht nur ein Nehmen sondern
auch ein Geben gehört.

Und wenn man einen Bug gefunden zu haben meint, sollte man ihn auch für
andere dokumentieren, damit die ihn vermeiden können.

Das ist ja jetzt das erste mal, daß du hier ein Programmtext
reinstellst.
Jetzt erst kann man damit anfangen, es nachzuvollziehen.
Mehr wollte ich ja garnicht.


Peter

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

So, ich hab jetzt mal Dein Programm getestet.

Natürlich mußte ich es erst noch erweitern, damit man auch was sieht.
Jeweils ins main und in die Interrupts habe ich LEDs eingebaut, damit
man sieht, ob sie ausgeführt werden.

Um nun in sleep zu kommen habe ich PINB0 genommen.
Und der Aufwachinterrupt fehlte völlig (vielleicht ist das ja Dein
Fehler).

Wie erwartet, funktioniert alles ganz genau nach Datenblatt.

Sobald sleep ausgeführt wird, bleiben alle LEDs stehen, d.h. die Timer
stehen wie ein Fels.
Und erst mit PINB2 (=INT0) wacht alles wieder auf.

Es wäre ja auch zu unwarscheinlich, daß so einen Bug bisher nie einer
bemerkt hätte.


Das erhärtet also meine Vermutung, daß Du nur am Symptom rumgedockert,
aber nicht die Ursache gefunden hast.


Peter

von Hagen (Gast)


Lesenswert?

@Peter, und schon hast du Zeit verplempert, ich habe auch noch nie was
davon gehört das der Power Down Modus nicht funktionieren sollte.

Es wäre schon sehr verwunderlich das im Power Down Modus, der ja den
Takt der MCU komplett abschaltet, immer noch alle von diesem Takt
abhängigen Timer laufen. Außnahme ist natürlich der asynchrone Timer
mit eigenem Takt, aber auch der sollte im Power Down Modus nicht mehr
laufen.

Gruß Hagen

von Mario (Gast)


Lesenswert?

Hallo Peter!


Das mit der Symptombekämpung ist leider in andern Bereichen Alltag.
Denk mal an die Medizin. Ich habe in meinem Leben noch keinen Arzt
getroffen, der nach der Ursache sucht.

Wenn sich der Patient dann selbst mit seiner Krankheit auseinandersetzt
und die Ursache findet, dann ist der Herr Doktor noch eingeschnappt,
weil er mit dir kein Geld mehr verdient.

Nur mal so am Rande.

Gruß Mario

von peter dannegger (Gast)


Lesenswert?

@Hagen,

Recht haste !

Irgendwie verarscht uns Richard total.


Wenn er nicht mal in der Lage ist, einen Fehler zu verfolgen oder zu
beschreiben oder Beispielcode mit Fehlerbild zu verfassen, dann gute
Nacht.

Hoffentlich macht er das Programmieren nur als Hobby und nicht für
kommerzielle Produkte. Rückrufaktionen fehlerhafter Produkte sind bei
so einem laxen Arbeitsstil unweigerlich vorprogrammiert.


Peter

von Hagen (Gast)


Lesenswert?

@Peter,

naja, Richard ist mir erstmal egal, ich habe nur DICH bedauert, weil du
dich so ins Zeug gelegt hast und somit auch sinnlos Zeit investiert
hast. Ich nehme ja an das auch du noch nie was von so einem Power Down
Fehler festgestellt hast. Sarkastisch gesagt kann ich mir das nur so
erklären das du recht behalten wolltest :-)

@Mario:

Sympthom-Bekämpfung in der Medizin beruht ja auf dem Fakt das die
Mediziner noch längst nicht alles wissen. ABER! in der
Softwareentwicklung baut man auf einem durch Menschenhand gebautem
Konstrukt auf. Dort gibt es nicht die kleineste Wissenslücke, darf es
garnicht. Ergo: in der Softwareentwicklung kann man zu jeder Zeit die
wikliche Ursache bekämpfen. Das es in der Realität NICHT so ist hat
meiner Meinung nach zwei Gründe:
1.) die heutigen Programmierer arbeiten öfters nach der Pi*Daumen
Logik, also nicht fundiert
2.) das nötige Wissen zur Softwareentwicklung wird schon an der Quelle
portioniert, sprich das Wissen ist nicht frei verfügbar, stattdessen
wird damit Geld verdient und Macht ausgeübt. Ich beziehe mich da zB.
auf die ominösen NDA's. Erst letzens suchte ich ein Datenblatt bei ALi
für einen stinknormalen RTC Baustein. Die wollten eine NDA von mir, shit
happens jetzt verbaue ich eben einen anderen. Als ob eine solche RTC
rießige Firmen-/Politische Geheimnisse enthalten könnte. Schlimmer
noch, es stellt sich heraus das deren RTC ein simpler Clone ist.

Gruß Hagen

von peter dannegger (Gast)


Lesenswert?

@Hagen

"Sarkastisch gesagt kann ich mir das nur so erklären das du recht
behalten wolltest :-)"


Ist bestimmt schon einigen aufgefallen, daß ich mich gerne durch betont
falsche Aussagen zur Richtigstellung und Erklärung hinreißen lasse.


Mit dem Power Down hatte ich bisher noch nichts gemacht, da alle meine
Geräte netzbetrieben sind.
Deshalb hab ichs mal ausprobiert und eben festgestellt, daß es ganz
genau nach Datenblatt funktioniert, war also nicht ganz umsonst.


Und sogar das SEI im Interrupt ist in diesem Falle gefahrlos, da ja der
aufweckende externe Interrupt keinen Wiedereintritt in den
Timerinterrupt zuläßt, er ist ja in der Abarbeitungsreihenfolge davor.
Sieht man sehr schön an meinem Beispiel. Bei gedrückter PINB2-Taste
wechseln zwar die LEDs im Main, die im Timerinterrupt bleiben aber
stehen.


Peter

von Gottfried (Gast)


Lesenswert?

In diesem Code sehe ich mehrere Fehler:

1. Der Sleep befehl wird in einer ISR ausgeführt und kann bei einem 
"echten" PowerDown nicht mehr aufwachen, da ein Interrupt diesen 
aufwecken muss.

2. Das setzen der Register
...
  in temp, MCUCR      ;PowerDown einstellen:
  sbr temp, 1<<SM1
  out MCUCR, temp    ;PowerDown eingestellt

; Hier der Fehler
  ldi temp, 1<<SE    ;Hier wird das temp Register mit 0v10000000 geladen
  out MCUCR, temp      ;Hier steht in MCUCR 0x80 drinnen und der 
Sleepmode ist auf den Idle modus geschaltet

; Richtig währe anstelle von ldi: ORI temp, 1<<SE


  sei                 ;Interrupts ermöglichen (sonst wacht nicht auf).
; Während einer Interrupt Routine darf der Interrupt nicht eingeschaltet 
werden!

  sleep
  cli
; Nach dem erwachen aus dem Sleep Modus sollte das Bit SE wieder 
gelöscht werden
...

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.