Hi! Ich habe folgendes Problem: Beim Auftreten einer fallenden Flanke an einem externen Interrupt Eingang (INT6), soll der µC in den Power-Down Modus gehen. Soweit so gut, das klappt alles Nun will ich aber, dass er mir bei einer steigenden Flanke wieder zu leben zieht. Laut Datenblatt S.90 steht da folgendes: "Low level interrupts and the edge interrupt on INT3:0 are detected asynchronously. This implies that these interrupts can be used for waking the part also from sleep modes other than Idle mode. The I/O clock is halted in all sleep modes except Idle mode." sowie "Note that if a level triggered interrupt is used for wake-up from Power-down mode, the changed level must be held for some time to wake up the MCU. This makes the MCU less sensitive to noise." Fürs Wecken verwende ich INT2, demnach müsste das doch eigentlich klappen? Kann mir einer sagen, warum es trotzdem nicht geht? Können nur fixe Logische Pegel den µC wieder aufwecken? Vielen Dank und schöne Grüße Philipp
Philipp Putzer wrote: > Kann mir einer sagen, warum es trotzdem nicht geht? Können nur fixe > Logische Pegel den µC wieder aufwecken? Im Power-Down-Modus ist der CPU-Takt deaktiviert. Für einen Flanken-Interrupt wird dieser aber benötigt. Deshalb steht im entsprechenden Abschnitt im Datenblatt auch, dass nur ein externer *Level*-Interrupt den µC aus dem Power-Down aufwecken kann, weil ein Level-Interrupt keinen Takt zur Synchronisation benötigt.
Johannes M. wrote: > Philipp Putzer wrote: >> Kann mir einer sagen, warum es trotzdem nicht geht? Können nur fixe >> Logische Pegel den µC wieder aufwecken? > Im Power-Down-Modus ist der CPU-Takt deaktiviert. Hmmm... - Der (der CPU-Takt) ist bei Idle auch deaktiviert. ;-) Daher hat der Takt, der für I/O zuständig ist, vermutlich einen anderen Namen, sorry. Aber ansonsten ist das alles richtig. > Für einen > Flanken-Interrupt wird dieser aber benötigt. Deshalb steht im > entsprechenden Abschnitt im Datenblatt auch, dass nur ein externer > *Level*-Interrupt den µC aus dem Power-Down aufwecken kann, weil ein > Level-Interrupt keinen Takt zur Synchronisation benötigt. ...
Philipp Putzer wrote: > Fürs Wecken verwende ich INT2, demnach müsste das doch eigentlich > klappen? Upps, das hatte ich doch beim ersten Mal glatt übersehen... Mit INT2 müsste es tatsächlich klappen, weil der (wie auch INT3, 1 und 0) asynchron detektiert wird. Hatte gedacht, Du wolltest ihn auch mit INT6 wieder zurückholen... Also wie gesagt, mit INT2 müsste es eigentlich auch auf Flanke klappen. @Hannes: Hast natürlich recht, sollte I/O-Takt anstelle von CPU-Takt heißen (bzw. der eigentliche Hauptunterschied zum Idle ist eben, dass der Hauptoszillator komplett abgeschaltet wird...)
Eben, es müsste ja eigentlich klappen Auf S.48 in der Tabelle für die Weckquellen aus den verschiedenen sleep-modi steht ja auch bei wake up source, INT3:0 or level interrupt INT4:7. Da denke ich kann jedes INT3:0 gehen. Wenn ich den Eintritt in den Power-down auskommentiere, funkt mein Int2 einwandfrei mit der steigenden Flanke. Nur weckt es den nicht mehr auf! Kann es damit zu tun haben, dass die Fuses für die Warmlaufzeit nicht richtig gesetzt sind? Bei mir sind CKSEL3:0, SUT1:0 programmiert (16MHz externer Quarz)
Nein, damit kann es nicht zu tun haben, das ist dem Controller egal. Er braucht halt die eingestellte Zeit, um wieder anzufahren, mehr nicht. >Wenn ich den Eintritt in den Power-down auskommentiere, funkt mein Int2 >einwandfrei mit der steigenden Flanke. Nur weckt es den nicht mehr auf! Dann ist dort irgendetwas nicht korrekt. Oder aber in der Initialisierung des Sleep-Modes. Wie ist denn der Zustand Deines Int-Pins vor dem Eintritt in den Tiefschlaf? Zeit, etwas Code zu posten!
Anbei der Code. Beim INT6 hängt ein TTL Ausgang eines Komperators, der bei Abfall der Betriebsspannung unter 9V auf Masse schaltet (fallende Flanke also) Damit geht gleichzeitig der INT2 auf High, und belibt da so lange, bis a) der Komp. wieder in den ursprünglichen Zustand schaltet b) eine andere Versorgung angeschlossen wird Trifft a oder b zu, dann tritt eine fallende Flanke am INT2 auf, und soll den µC wecken.
Kann auch nicht klappen, weil Du in der ISR den sleep-Befehl ausführst. Zu dem Zeitpunkt ist aber das I-Bit im SREG gelöscht und damit ist die Bearbeitung sämtlicher Interrupts gesperrt. Dementsprechend kann der INT2 gar nicht auslösen. Ein nicht freigegebener Interrupt kann nunmal den µC nicht aufwecken. Du musst entweder das sleep_mode() im Hauptprogramm ausführen (empfohlene Vorgehensweise) oder aber (etwas weniger empfehlenswert) das I-Bit in der INT6-ISR vor dem sleep_mode() wieder setzen. Ich hoffe, Du siehst jetzt endlich auch, wie wichtig es ist, den Code zu posten. Hätte ich das sofort gesehen, dann wäre Dein Problem vermutlich längst gelöst...
Stimmt! OK, daran hatte ich nun glatt nicht gedacht Ich werds dann mal heute abend testen, mit ausführung des sleep modes im Hauptprogramm! Vielen, vielen Dank auch!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.