Sleep-mode am Beispiel des ATtiny44

Der sleep mode (Schlafmodus) wird immer dann benötigt, wenn es darum geht den Stromverbrauch eines Mikrocontrollers zu senken.

Beispielsweise bei batteriebetriebenen Anwendungen (Fernbedienung etc.) ist dies sehr wichtig.
Wird der Mikrocontroller in einen sleep mode versetzt, werden verschiedene Funktionen (UART, Timer, ADC usw.) ausgeschaltet um Strom zu sparen.

Der sleep mode ist in verschiedenen Modi eingeteilt, je nachdem, welche Funktionen deaktiviert sind oder nicht.

3 sleep Modi - ATtiny44

Der tiny44 von ATMEL verfügt über drei sleep modes:

  • Idle
  • Stand-by
  • Power-down

Im Power-down mode wird beispielsweise am wenigsten Strom verbraucht (ca. 0,3µA). In diesem Modus wird der Oszillator und alle clocks gestoppt. Nur durch einen externen Reset, Watchdog Reset, Brown-out Reset, oder externen Level-Interrupt kann der Mikrocontroller geweckt werden.

In jedem Modus sind verschiedene Funktionen deaktiviert. Welche das genau sind, entnehmen Sie dem Datenblatt. Zu beachten ist z.B. dass die CPU nur im idle-mode mit einem Flankeninterrupt (INT0) geweckt werden kann. Im Stand-by bzw. power-down mode kann die CPU nur mit einem Level-Interrupt (INT0) aufgeweckt werden.

 

sleep-mode in C programmieren

Hier ein Beispiel in C, wie bei einem tiny44 der sleep mode (hier power-down mode) programmiert wird.
Als erstes wird unter main() das jeweilige Bit im Register MCUCR gesetzt um den sleep mode zu aktivieren. Danach wird der gewünschte sleep-mode "vorbereitet" (der idle-mode wurde auskommentiert).

Wird ein AD-Wandler im Programm verwendet, muss dieser vor der Aktivierung des sleep-modes deaktiviert werden.

In der Interrupt-Service-Routine (ISR0) wird die MCU dann mit einem Level-Interrupt aufgeweckt.
Zuerst wird der sleep-mode beendet. Danach wird der ADC (falls vorhanden) aktiviert. Gefolgt vom Programmcode wird am Ende der ISR der sleep-mode wieder aktiviert.

void main(void)
{

MCUCR |= (1<<SE); // Sleep enable

//set_sleep_mode(SLEEP_MODE_IDLE); // Sleep Mode "idle" vorbereiten

set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Sleep Mode "power down" vorbereiten

while(1)

{

ADCSRA &= !(1<<ADEN); // ADC deaktivieren

sleep_mode(); // Start sleep mode

}

}

ISR(INT0_vect)

{

MCUCR &= ~(1<<SE); // Sleep disable

ADCSRA |= 1<<ADEN; // ADC aktivieren

...

...

...

MCUCR |= (1<<SE); // Sleep enable

}