AVR-Tutorial: Power Management: Unterschied zwischen den Versionen
Zeile 20: | Zeile 20: | ||
Viele Mikrocontroller können einzelne Funktionsblöcke abschalten. Bei den AVRs schlägt da vor allem der 16-Bit-Timer 1 zu Buche. Aber auch die Referenzspannungsquelle für den A/D-Wandler, Analogvergleicher oder den Brown-Out-Detektor kann man abschalten. | Viele Mikrocontroller können einzelne Funktionsblöcke abschalten. Bei den AVRs schlägt da vor allem der 16-Bit-Timer 1 zu Buche. Aber auch die Referenzspannungsquelle für den A/D-Wandler, Analogvergleicher oder den Brown-Out-Detektor kann man abschalten. | ||
Für die Kontrolle der Stromaufnahme aus einer Batterie ist ein Digitalmultimeter mit vielen Strommessbereichen bis 20 µA (Auflösung 10 nA) vorteilhaft. Außerdem ein Plättchen einer doppelseitigen Leiterplatte mit dünnen Drähtchen, das man unter die Batteriekontaktierung schieben kann. Weicht die Stromaufnahme vom Datenblatt ab, hat man wohl noch irgendetwas vergessen. | |||
=== Sleep Modi === | === Sleep Modi === |
Version vom 5. August 2013, 14:07 Uhr
ACHTUNG! Dieser Artikel befindet sich noch im Aufbau!
Vorallem in batteriebetriebenen Systemen spielt die Leistungsaufnahme eine wichtige Rolle, d.h. sie soll so niedrig wie möglich gehalten werden um eine lange Laufzeit zu erreichen. Den sparsamen Umgang mit der verfügbaren el. Ladung nennt man Power Management (dt. Energiesparen).
Im Rahmen des Power Managements stehen uns beispielsweise die Sleep-Modi zur Verfügung, mit denen wir bestimmte Module zeitweise deaktivieren können. Andere garnicht genutzte Module können wir durch entsprechende Konfiguration (z.B. in den Fuses) auch komplett deaktivieren.
Theorie
Der Stromverbrauch einer CMOS-Schaltung (was auch Mikrocontroller sind) hängt letztlich nur davon ab, wie viele Gates bei welcher Spannung umgeladen werden. Zur Reduktion steht demnach zur Verfügung:
- Reduktion der Umladevorgänge pro Sekunde, also Reduktion der Taktfrequenz
- Reduktion der beteiligten Kapazitäten, also Abschalten nicht benutzter Funktionsblöcke
- Reduktion der Speisespannung (bei manchen Controllern ist das die Kernspannung)
Den statischen Reststrom kann man heutzutage vernachlässigen, auch wenn an dieser Stelle die Anmerkung fallen muss, dass AVRs da eher schlecht abschneiden. Hingegen muss Strom durch ohmsche Lasten, etwa Pull-Up-Widerstände oder LEDs, unbedingt beachtet werden! Außerdem dürfen keine offenen (CMOS!-)Eingänge „herumfliegen“ sondern müssen allesamt an definiertem Potenzial liegen. In der Regel können Mikrocontroller unbenutzte Eingänge im Schlafmodus oder Analogeingangsbetrieb automatisch abtrennen.
Grundsätzlich sollte für Stromsparbetrieb die niedrigstmögliche Taktfrequenz gewählt werden, die möglich ist. Übliche Mikrocontroller können direkt von einem Uhrenquarz mit 32,768 kHz gespeist werden. Macht natürlich auch nur maximal 32768 Befehle pro Sekunde. Die Stromaufnahme ist dabei sehr gering und im Gegensatz zu Sleep-Mode-Tricksereien ohne hohe Spitzen.
Da das Antwortverhalten bei derart geringen Taktfrequenzen leidet, wird man eine höhere Frequenz wählen und den Prozessor bei Nicht-Bedarf schlafen schicken. Die Strom-Spitzen sind dementsprechend höher, die Gesamtstromaufnahme bleibt jedoch gering.
Viele Mikrocontroller können einzelne Funktionsblöcke abschalten. Bei den AVRs schlägt da vor allem der 16-Bit-Timer 1 zu Buche. Aber auch die Referenzspannungsquelle für den A/D-Wandler, Analogvergleicher oder den Brown-Out-Detektor kann man abschalten.
Für die Kontrolle der Stromaufnahme aus einer Batterie ist ein Digitalmultimeter mit vielen Strommessbereichen bis 20 µA (Auflösung 10 nA) vorteilhaft. Außerdem ein Plättchen einer doppelseitigen Leiterplatte mit dünnen Drähtchen, das man unter die Batteriekontaktierung schieben kann. Weicht die Stromaufnahme vom Datenblatt ab, hat man wohl noch irgendetwas vergessen.
Sleep Modi
Welche Sleep-Modi es gibt, hängt vom verwendeten µC ab, dieser Artikel nimmt jedoch Bezug auf den ATmega32. Um einen der verfügbaren Sleep-Modi des ATmega32 zu betreten müssen folgende Schritte ausgeführt werden
- Das SE-Bit im MCUCR-Register wird auf 1 gesetzt
- Die SMx-Bits im MCUCR-Register je nach gewünschtem Modus setzen
- Der SLEEP-Befehl wird ausgeführt
Der Mikrocontroller geht dann sofort in den SLEEP-Modus, d.h. noch vor eventuell anstehenden Interrupts, und wacht erst wieder auf wenn ein Signal eines geeigneten Moduls (je nach Modus) ihn aufweckt.
Die Arbeit wird dann mit der ersten Anweisung hinter dem SLEEP-Befehl wieder aufgenommen.
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
Bezeichnung | SE | SM2 | SM1 | SM0 | ISC11 | ISC10 | ISC01 | ISC00 |
- Bit 7 - SE
- Sleep Enable
- Mit diesem Bit wird bestimmt ob der Sleep-Befehl ausgeführt wird (1) oder nicht (0).
- Bit 6..4 - SM2..0
- Sleep Mode Select
- Mit diesen drei Bits wird der gewünschte Sleep-Modus gewählt
SM2 | SM1 | SM0 | Sleep Modus |
---|---|---|---|
0 | 0 | 0 | Idle |
0 | 0 | 1 | ADC Noise Reduction |
0 | 1 | 0 | Power-down |
0 | 1 | 1 | Power-save |
1 | 0 | 0 | Reserved |
1 | 0 | 1 | Reserved |
1 | 1 | 0 | Standby(1) |
1 | 1 | 1 | Extended Standby(1) |
(1) Nur verfügbar mit externem Taktgeber
Modi Übersicht
Generell ist der Modus zu wählen, der die meisten nicht benötigten Module abschaltet.
Aktive Takte | Aktive Oszillatoren | Weckquellen | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Sleep Modus | clkCPU | clkFLASH | clkIO | clkADC | clkASY | Haupttaktgeber | Timer Oszillator | INT2 INT1 INT0 |
TWI Address Match | Timer2 | SPM/EEPROM Ready | ADC | Andere I/O |
Idle | x | x | x | x | x(2) | x | x | x | x | x | x | ||
ADC Noise Reduction | x | x | x | x(2) | x(3) | x | x | x | x | ||||
Power-down | x(3) | x | |||||||||||
Power-save | x(2) | x(2) | x(3) | x | x(2) | ||||||||
Standby(1) | x | x(3) | x | ||||||||||
Extended Standby(1) | x(2) | x | x(2) | x(3) | x | x(2) |
(1) Nur verfügbar bei externer Taktquelle
(2) Wenn AS2-Bit in ASSR-Register gesetzt
(3) Nur INT2 oder Level Interrupt INT1 und INT0
Manuelles Deaktivieren
Einzelne Module können auch manuell deaktviert werden um Strom zu sparen, das bietet sich vorallem an wenn bestimmte Module im gegebenen Projekt generell nicht benötigt werden und damit deaktiviert werden können.
Analog to Digital Converter
todo...
Analog Comparator
Der Analogkomparator ist standardmäßig aktiviert. Um ihn zu deaktivieren, muss man ACD (Bit 7) im Register ACSR setzen.
Brown-Out Detector
Der Brown-Out Detector lässt sich entweder durch das BODEN-Bit in den Fuses oder mit entsprechenden Befehlen aktivieren oder deaktivieren. Das Fuse-Bit ist standardmäßig gesetzt (Achtung: Umgekehrte Logik!) und der BOD damit deaktiviert.
Watchdog
Auch der Watchdog-Timer lässt sich in den Fuses standardmäßig aktivieren/deaktivieren, hier über das WDTON-Bit. Natürlich geht auch das softwareseitig [1]
Praxis
Assembler
TODO: ASM-Quellcode Beispiele
C
Ein simples Testprogramm, um mit sleep modi im AVR zu spielen. Es funktioniert sehr gut mit dem ATmega8 und ist auch auf andere AVRs portierbar. Teilweise sind weitere Modi verfügbar.
Wichtig ist, daß die Interruptroutine für den "Weckruf" vorhanden sein muss. Es müssen nicht zwingend Aktionen in ihr durchgeführt werden.
/* ATmega8 with internal 4Mhz clock (6cycle + 64ms) */
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <util/delay.h>
int main(void)
{
DDRC |= (1 << PC2) | (1 << PC1); // leds for testing
DDRD &= ~(1 << PD2); // INT0: input...
PORTD |= (1 << PD2); // ...with pullup.
// level interrupt INT0 (low level)
MCUCR &= ~((1 << ISC01) | (1 << ISC00));
// infinite main loop
while (1)
{
// trigger leds for testing
PORTC ^= (1 << PC1);
_delay_ms(500);
PORTC ^= (1 << PC1);
// enable external interrupt
GICR |= (1 << INT0);
// set sleep mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
// sleep_mode() has a possible race condition
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
// waking up...
// disable external interrupt here, in case the external low pulse is too long
GICR &= ~(1 << INT0);
// disable all interrupts
cli();
}
}
ISR(INT0_vect)
{
// ISR might be empty, but is necessary nonetheless
PORTC ^= (1 << PC2); // debugging
}
Quellen