Guten Abend, da ich mir einfach nicht mehr zu helfen weiß, frage ich jetzt einfach hier mal. Mein Problem: Da meine Schaltung von einer Batterie versorgt werden soll, möchte ich bei meinem Atmega168 den Power-Down Mode verwenden. Da der uC jederzeit über die USART Schnittstelle Daten empfangen können muss, muss ich auch in der Lage sein über diese Schnittstelle aufzuwachen. Leider werde ich aus dem Datenblatt nicht schlau. Quellen, die den uC aus dem Power-Down Mode aufwecken können, sind: 1.) INT1, INT0 (only level interrupt) 2.) TWI address match 3.) WDT Was genau versteht man unter einem Level Interrupt? Wäre es möglich, die USART Pins vor dem Übergang in den Power-Down mode so umzukonfigurieren, dass am RX Pin ein Pin change registriert werden könnte? Es wäre kein Problem über USART zunächst eine Art Wakeup Pattern zu senden und erst nach dem Aufwachen die eigentlichen Nutzdaten. Was meint ihr? Gibt es eine Möglichkeit den uC via USART aus dem Power Down zu holen? Ich danke euch schon mal im Voraus.
Die Idee mit "eine Art Wakeup Pattern" klingt doch ganz gut, einfach mal ausprobieren; ich bin der Meinung, das sollte klappen, wenn die Übertragungsrate nicht zu hoch ist.
Sabse schrieb: > Quellen, die den uC aus dem Power-Down Mode aufwecken können, > sind: > > 1.) INT1, INT0 (only level interrupt) > 2.) TWI address match > 3.) WDT Nicht nur, da steht auch Pinchange. Während die INT0 und INT1 keinen auf Flanken getriggerten IRQ erlauben, weil die Logik nicht aktiv ist, gilt das aber nicht für Pinchange Interrupts. D.h. ein Flankenwechsel bei aktivierten PC Interrupt weckt den MC. Es ist also möglich, z.B. auf den RXD Pin einen Pinchange Interrupt zu legen, dieser wird den MC auch aus Powerdown aufwecken.
Wie Matthias schrieb ist es der Pin-Change Interrupt auf dem Rx Pin, der den Atmega168 wecken kann/wird wenn hier auf dem UART was rein kommt während der Atmega168 schläft.
Hallo, Als Ergänzung möchte ich den Attiny841 in's Gespräch bringen, er erkennt in alle 4 Sleepmode das Startbit und der µC wacht auf. Evtl. lohnt es sich einen anderen µC ein zusetzen ?
Es geht durchaus mit einem ATmega168. Wie von den Vorrednern skizziert: mit dem Pin-change auf RxD, also PCINT16, arbeiten, als 'wake-up-pattern' 0xFF verwenden.
@ S. Landolt (Gast) >Es geht durchaus mit einem ATmega168. Wie von den Vorrednern skizziert: >mit dem Pin-change auf RxD, also PCINT16, arbeiten, als Ja. >'wake-up-pattern' 0xFF verwenden. Das ist vollkommen schnuppe, denn es gibt so oder so einen Pinwechsel vom Dauerstop (= High) zum Startbit (low).
Falk Brunner schrieb:
> Das ist vollkommen schnuppe
Da würde mich Ihre Lösung interessieren; bei meiner wird nach dem PCINT
ebendieser ab- und USART eingeschaltet, und Letzterer liefe bei einem
beliebigen Muster auf einen Fehler.
Das ist die wirklich interessante Frage - erkennt das USART noch dieses Startbit und kann seine Abtastung drauf einrasten oder nicht. Ich habs noch nicht ausprobiert, kann mir aber vorstellen, das die Dauer des Oszillatorstart sowie die Taktfrequenz darauf Einfluss haben. Eine langsame Baudrate könnte auch nützlich sein.
Falk B. schrieb: >>'wake-up-pattern' 0xFF verwenden. > > Das ist vollkommen schnuppe, denn es gibt so oder so einen Pinwechsel > vom Dauerstop (= High) zum Startbit (low). Das Pattern ist nicht ganz unwichtig, wenn die UART-Logik des AVR auch erst zusammen mit dem Wakeup aufwacht. Die damit in Verbindung stehende Verzögerung kann zu Datenschrott führen. Beim Pattern 0xFF, ggf. zusammen mit einer zum Taktgenerator passenden Wartezeit, ist nach dem Startbit nie low auf der Leitung. Folglich wird entweder überhaupt nichts erkannt, oder 0xFF. Aber kein Schrott.
an Matthias Sch. Vielleicht mache ich ja etwas falsch, aber ich schaffe es nicht, auch nicht mit internem RC-Oszillator und UBRR=4095.
> und was schaffst du nicht?
Mit einem anderen Muster als 0xFF zu arbeiten oder gleich den UART
während des Power-downs durchlaufen zu lassen.
bei einem anderen Muster musst du natürlich abwarten (sowohl auf mc als auch auf PC Seite) bis das Byte durchgelaufen ist und erst dann auf UART umschalten, bzw die eigentlichen Nutzbytes senden
Dann müsste ich eine, von der Übertragungsrate abhängige Zeitspanne warten; bei 0xFF kann ich sofort umschalten.
@A. K. (prx) >> Das ist vollkommen schnuppe, denn es gibt so oder so einen Pinwechsel >> vom Dauerstop (= High) zum Startbit (low). >Das Pattern ist nicht ganz unwichtig, wenn die UART-Logik des AVR auch >erst zusammen mit dem Wakeup aufwacht. Jain. >Die damit in Verbindung stehende >Verzögerung kann zu Datenschrott führen. Dagegen muss eine STABILE UART-verbindung so oder so ausgelegt sein und sich nich einfach mal so aus dem Tritt bringen lassen. >Beim Pattern 0xFF, ggf. >zusammen mit einer zum Taktgenerator passenden Wartezeit, ist nach dem >Startbit nie low auf der Leitung. Folglich wird entweder überhaupt >nichts erkannt, oder 0xFF. Aber kein Schrott. Der Ozillator braucht nach einem Power-Down sowieso ein gehörige Zeit zum Anlaufen. Und selbst wenn es schnell geht (RCO, externer Takt), kann man schlicht eine Zeichen-Zeit mit busy wait vertrödeln. So what!
an Falk Brunner Mir ist nach wie vor unklar, wie Sie das Ende eines beliebigen Aufwach-Musters erkennen, besonders bei Verwendung eines Quarzes mit seiner längeren Anlaufzeit.
@ S. Landolt (Gast) >Mir ist nach wie vor unklar, wie Sie das Ende eines beliebigen >Aufwach-Musters erkennen, besonders bei Verwendung eines Quarzes mit >seiner längeren Anlaufzeit. ??? Man wartet direkt nach dem Aufwachen im Interrupt einfach eine komplette Zeichenzeit (=10 Bit) und schaltet dann erst den UART RX Teil ein. Da ist man so oder so auf der sicheren Seite. Wo liegt das Problem?
> Wo liegt das Problem?
Dass der Quarz zu Beginn nicht stabil läuft, die Messung der Byte-Zeit
also ungenau wird; bei Verwendung des RC-Oszillators geht das, aber ganz
einfach wird es ohne diese Zeitmessung unter Ausnutzung von 0xFF,
insofern betrachte ich es nicht als 'schnuppe'.
@ S. Landolt (Gast) >> Wo liegt das Problem? >Dass der Quarz zu Beginn nicht stabil läuft, die Messung der Byte-Zeit >also ungenau wird; Quark. Solange der Quarz noch anläuft, läuft die CPU so oder so nicht. https://www.mikrocontroller.net/articles/Sleep_Mode#Morgenmuffel Und selbst wenn der Quarz noch nicht "perfekt" eingeschwungen ist, ist dessen Frequenzfehler kleiner 1 Promille und damit für diese Zeitverzögerung mehr als genau genug. > bei Verwendung des RC-Oszillators geht das, aber ganz >einfach wird es ohne diese Zeitmessung unter Ausnutzung von 0xFF, >insofern betrachte ich es nicht als 'schnuppe'. Ich schon. Man kann auch 0x00 nehmen, dann ist der Puls breiter, aber ohne 2. fallende Flanke (welche der UART als STOP-START Übergang identifizieren würde). Oder 0x0F, 0x7F oder, oder oder. Wollen wir weiter philosophieren?
Als "philosophieren" würde ich es nicht bezeichnen, es geht schließlich um eine handfeste technische Lösung. Aber vermutlich würden Sie es mit den unterschiedlichen Mustern auch zum Laufen bringen, so wie ich es mit dem 0xFF erreichte. Und da sich offenbar der ursprüngliche Fragesteller bereits verabschiedet hat, mache das gleiche.
Einen schönen guten Morgen und ein gutes neues Jahr Euch allen!! Der Urlaub ist zu Ende und ich freue mich über all die Antworten von Euch. Vielen Dank. Ich bin gerade an der Implementierung und wollte euch fragen, was ihr davon haltet: Bevor ich in den Power Down Mode gehe rufe ich folgende Funktion auf:
1 | void USART_WAKE_UP_MODE(void) |
2 | {
|
3 | //The uC have to wake up from Power Down by PCINT16 (RX)
|
4 | |
5 | //Disable USART RX
|
6 | UCSR0B &= ~(1<<RXEN0); |
7 | |
8 | //Disable RX Complete Interrupt
|
9 | UCSR0B &= ~(1<<RXCIE0); |
10 | |
11 | //Enable PCIE2 --> PCINT23...16
|
12 | PCICR = (1<<PCIE2) | (0<<PCIE1) | (0<<PCIE0); |
13 | |
14 | //Enable PCINT16 in mask
|
15 | PCMSK2 = (1<<PCINT16); |
16 | }
|
Das sollte mich im Moment des Aufwachens zu folgendem Interrupt führen:
1 | ISR (PCINT2) |
2 | {
|
3 | //Change RX Pin to USART Mode
|
4 | USART_NORMAL_MODE(); |
5 | }
|
6 | [/code] |
7 | |
8 | [c] |
9 | void USART_NORMAL_MODE(void) |
10 | {
|
11 | //Disable Pin Change interrupt
|
12 | PCICR &= ~(1<<PCIE2); |
13 | PCMSK2 &= ~(1<<PCINT16); |
14 | |
15 | //Enable USART RX
|
16 | UCSR0B |= (1<<RXEN0); |
17 | |
18 | //Enable RX Complete Interrupt
|
19 | UCSR0B |= (1<<RXCIE0); |
20 | }
|
In der Theorie müsste er nun im USART Interrupt etwas empfangen:
1 | ISR (USART_RX_vect) |
2 | {
|
3 | //USART Receive Handler
|
4 | unsigned char c; |
5 | |
6 | c = USART_Getc(); /* get received byte */ |
7 | //Do something.
|
8 | |
9 | |
10 | //USART RX PIN back to Pin Change Interrupt
|
11 | USART_WAKE_UP_MODE(); |
12 | }
|
Nachdem ich etwas empfangen habe, sollte der RX Pin wieder in den Pin Change mode gehen. Was haltet ihr davon? Kann es leider noch nicht testen, da die Hardware noch fehlt. Schöne Grüße, Sabine.
Nur als kleiner Hinweise, vielleicht ist es ja möglich: Evtl. den neue ATmega168PB verwenden: Dessen UART kann jetzt auch die eingehenden Daten Puffern, während er aus dem Power-Down Mode aufwacht. Allerdings leider nicht mehr im DIP-Gehäuse verfügbar :-(
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.