ich will einen ATmega168A in den Power-Down Mode bringen und dann per INT0 aufwecken. Mir war dunkel in Erinnerung, dass das nur mit einem Level-Interrupt möglich sei. Also habe ich im Datenblatt nachgesehen bzw. den Datenblättern.
Denn in der Ausgabe von 2018 steht, dass das nur mit einem Level-Interrupt möglich sein. In der Ausgabe von 2020 fehlt diese Angabe. Im Errata des neueren Datenblatts steht lediglich "Removed footnote regarding interrupt modes for INT0 and INT1".
Tests mit dem ATmega168A haben gezeigt, dass das Wakeup auch mit Flanken-Interrupts funktioniert, also wie im neueren Datenblatt beschrieben.
Frage:
Weiß jemand, ob das nur ein Fehler und eine Korrektur im Datenblatt war oder ob diese Einschränkung bei älteren Controllern tatsächlich bestand?
In dem von S. L. angehängten Ausschnitt steht, dass für INT0 eine Flankenerkennung nur möglich ist, wenn der I/O-Clock läuft.
Das gleiche steht in dem von Oliver S. genannten Kapitel 10.5, also dass das Aufwachen aus dem Power-Down Mode nur mit einem Level-Interrupt an INT0 möglich ist.
Der Hinweis fehlt im aktuellen Datenblatt.
Und vor allem: Ich habe den Interrupt auf Flankenerkennung eingstellt und der Controller wacht aus dem Power-Down Modus auf.
Entweder habe ich das noch immer nicht verstanden oder einfach falsch programmiert...
Also, nach dem Aufwachen toggle ich eine LED. Das passiert nur dann, wenn der Controller geweckt wird, indem ich an PD2 eine fallende Flanke erzeuge (Taste). PD2 ist als Input mit Pull-Up konfiguriert und dazu dann der Interrupt auf fallende Flanke (abweichend von der genannten Vorlage, da ist es eine steigende Flanke).
Außerdem habe ich den Stromverbrauch geprüft. In der Phase im Power-Down Mode sind es nur einige uA, deswegen bin ich mir recht sicher, dass der Controller tatsächlich in diesem Modus ist.
Eine Taste prellt beim Drücken und beim Loslassen. Ob der Interrupt auf Pegel oder welche Flanke reagiert, kann man so nicht erkennen.
Du brauchst einen sauberen Taktgeber, z.B. einen 2. µC oder zur Not mit einem 555.
Wäre mal interessant, ob der Unterschied bei den ATmega164..1284/A/P/PA auch besteht.
Man hätte es aber besser in die neuen Datenblätter explizit reinschreiben sollen.
Nur eine Zeile weglassen, übersieht man leicht. Zumal es nicht an allen Stellen korrigiert wurde.
Ich hab noch einen alten ATmega644 von 2006 rumliegen mit nur einer UART.
All pins can be used as event input.
All pins can be used for external interrupt.
Asynchronous pin change sensing can wake the device from all sleep modes.
The PORT also supports asynchronous input sensing with interrupts and events for selectable pin change conditions. Asynchronous pin change sensing means that a pin change can trigger an interrupt and wake the device from sleep, including sleep modes where CLK_PER is stopped.
Ein ATmega16 wacht nicht auf, mein einziger ATmega16A ist unauffindbar, ein ATmega644 wacht auf, und für die anderen gehe ich auch von Letzterem aus (ATmega324PA, ATmega644P, ATmega1284P), erspare mir also den Test.
Also, normalerweise verwende ich dafür keinen Taster, das war nur zum Testen. In der eigentlichen Schaltung kommt ein Sensor zum Einsatz.
Dieser Sensor hat normalerweise ein Ausgangssignal von High. Wenn er dann das entspr. Ereignis bemerkt, wechselt er das Ausgangssignal auf Low. Wie lange das dann auf Low ist, kommt auf das Ereignis an.
Dafür ist ein Flanken-Interrupt einfacher, finde ich. Da muss ich das Interrupt auch nicht ein- und ausschalten, um eine Mehrfachtriggerung zu vermeiden. Insbesondere kann nach Abarbeitung des Interrupt-Codes der Controller schon wieder schlafen, während der Sensor noch ein Low-Signal ausgibt.
Mal ganz blöd gefragt: wie erzeugt man einen Rising Interrupt
ohne Level davor und danach?
Die Frage verstehe ich nicht - aber hier mein Vorgehen: INT0 (=PD2) mit externem Pull-down, Taster zieht auf high. Programm lässt LED langsam blinken, ein paar Sekunden lang, geht dann in Power-down. Dahinter liegt permanentes schnelles Blinken; Ablauf: nach den ersten Sekunden hört die LED auf zu blinken, ich betätige den Taster, anschließend sehe ich schnelles Blinken (oder eben nicht, bei den älteren Controllertypen).
Mal ganz blöd gefragt: wie erzeugt man einen Rising Interrupt ohne Level
davor und danach?
Beispielsweise mit einem Gewitter ;-)
Oder weißt Du wirklich nicht, was gemeint ist?
In Kürze:
Flankengetriggerte Interrupts werden durch eine Pegeländerung ausgelöst und müssen die Pegeländerung nicht bis zur Ausführung der betreffenden ISR beibehalten. Andernfalls ergibt sich ein 'spurious interrupt', der nicht bearbeitet wird.
Ferner kann die Flanke beliebig sein, während es bei pegelempfindlichen Interrupts einen passiven und einen aktiven Pegel gibt.