Energiesparen mit dem Register CLKPR


von Ralf Beesner, DK5BU
Elektronik-Labor   Projekte   AVR 





.... alte Pfade

Manchmal hält man ja lange an der naheliegenden Lösung fest, obwohl abseits des eingetretenen Pfades eine viel komfortablere Lösung wartet. So ging es mir mit dem "System Clock Prescaler" des AtTiny 13, der über das Register CLKPR gesteuert wird.

Als in der Analogtechnik aufgewachsenen fasziniert mich an Mikrocontrollern besonders, dass man mit wenig Aufwand Low-Power-Schaltungen erstellen kann, die jahrelang mit einer Batterieladung laufen.

Am einfachsten spart man Energie, indem man den Mikrocontroller zwischendurch in den Powerdown-Modus schickt; allerdings hat man dann keinen Takt und kann den Controller nur noch durch asynchrone externe Interrupts (INT0 bzw. Pin Change Interrupts) aus dem Tiefschlaf holen.

Benötigt man die Taktquelle ständig (z.B. für den Timer), darf man den AtTiny 13 lediglich in den Idle- Modus versetzen. Energie sparen kann man dann zunächst, indem man alle nicht unmittelbar nötigen Baugruppen (z.B. den ADC) abschaltet; darüberhinaus bleibt nur, den Controller mit geringerem Takt zu betreiben (die wenigsten Anwendungen sind so rechenintensiv, dass der Mikrocontroller mit 9,6 oder 1,2 MHz laufen muss).





Bisher hatte ich den Takt durch "Umfusen" des AtTiny 13 herabgesetzt. Man hat allerdings nur wenige Stufen: 9,6 MHz, 4,8 MHz, 1,2 MHz, 600 kHz, 128 kHz und 16 kHz - wobei die letzten beiden aus dem sehr ungenauen Watchdog-Timer abgeleitet werden.

Bei 128 kHz und 16 kHz läuft man allerdings Gefahr, dass der Programmieradapter zu schnell für den AtTiny ist, denn beim Flashen und Umfusen darf der Programmer-Takt nur maximal 1/4 des AtTiny-Takts betragen. Man kann sich also aus dem AtTiny "aussperren", wenn sich der Programmer- Takt nicht weit genug herabsetzen lässt.

Daher flashte ich AtTiny 13 meist mit Burkhard Kainkas MikroISP.exe aus dem "Lernpaket Mikrocontroller"; damit lässt sich der Attiny13-Clock sehr komfortabel umfusen, und der Programmiertakt ist so langsam, dass man sich auch bei 16 kHz Clock nicht aussperren kann.





.... neue Pfade

Die Verwendung des AtTiny- "System Clock Prescaler" ist weitaus eleganter. Man kann den AtTiny 13 auf 1,2 MHz (also dem Auslieferungszustand) belassen und erst im Programm den Takt herabsetzen oder sogar heraufsetzen.

Ist der AtTiny 13 auf 1,2 MHz geflasht, ist der System-Prescaler bereits im Einsatz und auf den Teilerfaktor 8 gestellt. Er lässt sich zur Laufzeit des Programms über das Register CLKPR auf die Teilerfaktoren 1 bis 256 umschalten.

Man kann also Taktraten von 9,6 MHz bis 37,5 kHz einstellen (und sogar während des Progammlaufes die Taktrate mehrfach umschalten). So kann man sein Mikrocontroller- Programm mit energiesparendem Takt - z.B. 37,5 kHz - betreiben, ohne die Fusebytes "anfassen" zu müssen.

Allerdings muss man auch hier sicherstellen, dass der verwendete  Programmieradapter sich auf genügend langsamen Takt umschalten lässt. Man sperrt sich nämlich auf diesem Wege besonders gründlich aus; zur Rettung des AtTiny reicht es nicht, Fusebytes mit einem langsamen Programmer auf Standardwerte zu setzen, sondern man muss das Programm löschen oder austauschen.


Das Umschalten geht recht einfach; Atmel hat allerdings eine Sicherheitsmassnahme gegen versehentliches Umschalten des Taktes eingebaut:

Man muss zunächst lediglich das oberste Bit im Register CLKPR auf "1" setzen (alle anderen Bits müssen "0" sein) und hat dann 4 Takte Zeit, durch Beschreiben der 4 unteren Bits die neue Taktrate einzustellen (das oberste Bit muss dabei auf "0" stehen). Auch müssen Interruts deaktiviert sein, damit sie nicht in das 4-Takte-Zeitfenster „hineinfunken“.

Damit die auf Waitstates beruhenden BASCOM- Befehle richtig rechnen, muss man dem Compiler die Ziel-Taktrate über den Befehl "$crystal" mitteilen:

Beispiel 1:

$crystal = 37500                             ' Attiny ist jedoch auf 1,2 MHz geflasht
........                                               ' hier haben wir noch 1,2 MHz Takt

CLKPR = &B10000000
CLKPR = &B00001000                      
CLKPR = &B00001000 
........                                               ' ab hier geht es mit 37,5 kHz weiter


Beispiel 2:

$crystal = 9600000                      ' Attiny ist jedoch auf 1,2 MHz geflasht
........                                            ' hier haben wir noch 1,2 MHz Takt

CLKPR = 128
CLKPR = 0                      
CLKPR = 0
........                                           ' ab hier geht es mit 9,6 MHz weiter


Der "System Clock Prescaler" ist in den neueren Atmel- Designs enthalten - z.B. AtMega 48 / 88 / 168 / 328, AtTiny 24 / 44 / 84, Attiny 25 /45 /85, AtTiny 2313.  Die ältere Generation AtMega 8 / 16 /32  oder AtTiny 26 enthält ihn noch nicht.

Den Anstoß zur Beschäftigung mit dem "System Clock Prescaler" erhielt ich durch ein RC- Fernsteuerungs-Schaltmodul von Hannes Lux. Da es dazu dient, das Soundmodul in einem ferngesteuerten Enten-Modell zu schalten, erhielt es von ihm den prägnanten Namen "gaakgaak.bas" (wegen seines einzigartigen Namens ist es leicht über Google oder andere Suchmaschinen zu finden).

Hannes hat – ohne das näher zu erläutern – den CLKPR- Befehl mit dem neuen Teilerverhältnis zweimal aufgerufen (ich habe das in dem obigen Beispiel übernommen). Im Datenblatt steht das so nicht.

Beim Messen des Stromverbrauchs zeigte sich, dass der 9,6 Mhz- Oszillator  mit der nachgeschalteten Teilerkette doch deutlich mehr Strom verbraucht als der ungenaue 128 kHz-Watchdog-Oszillator. Ein guter Kompromiss ist der 4,8 Mhz-Oszillator plus Teilerkette, aber dann muss man den AtTiny 13 umfusen.




Elektronik-Labor   Projekte   AVR