Kapitel 1: Das CLKPR-Register
Hallo zusammen,
ich beginne mal wieder mit einer kurzen Story. Vor ein paar Wochen mit einem befreundeten Cacher verabredet, um an einem seiner Caches eine RL-Stage zu installieren - das RL hatte er schon und war nun dabei etwas Tarnung drumherum zu bauen ... da kam der Anruf: die Tag-/Nachschwelle passt noch nicht (das RL wäre wohl nie in den Tagmodus gegangen) und ob man das nicht anpassen könnte. Also das alte Notebook mit dem alten seriellen Programmer eingepackt und los.
Tja und da saß ich nun. Der auf 128kHz getaktete Tiny ließ sich mit dem Programmer nicht ansprechen (keine Ahnung warum, früher war das kein Problem) und so endete das Ganze damit, dass ein neuer Tiny programmiert wurde und nun mit der originalen Taktfrequenz von ca. 1MHz im Baum hängt.
Aber nach diesen Problemen fiel mir doch wieder ein, was ich schon lange mal ausprobieren und für die RL nutzen wollte: das CLKPR-Register! Dieses Register hat eine ähnliche Aufgabe wie das CKDIV8-Fuse: es teilt den vom Oszillator bereitgestellten Takt runter, bevor daraus der µC-Takt erzeugt wird. Allerdings kommt das CLKPR-Register erst während der Programmlaufzeit zum tragen und es kann den Takt etwas feiner unterteilen (nicht nur 1:8, sondern von 1:2 bis 1:256 in allen Zweierpotenzen).
Hat jemand Erfahrungen mit diesem Register und hat es schon einmal genutzt? Folgende Hoffnung hatte ich damit jedenfalls: man lässt den µC auf den Werkseinstellungen (9,6MHz Oszill. (des Tiny 13) mit gesetzter CKDIV8-Fuse: Takt = 1,2MHz) und teilt den Takt erst im Programm durch Setzen des CLKPR-Registers weiter runter (ginge bis runter auf 37,5kHz). Damit hätte man beim Programmieren einen ordentlich flotten Tiny und während des Programmlaufs einen schön sparsamen. So dachte ich jedenfalls! Aber da hat mir Atmel einen Strich durch die Rechnung gemacht.
Die Experimente zum Runterteilen des Taktes habe ich mit einem Tiny 25 gemacht, da dieser ein CLKO-Pin besitzt, über den man den aktuellen µC-Takt von außen abfragen kann. Zunächst: das CLKPR-Register funktioniert perfekt. Man kann damit wunderbar den Takt während des Programmlaufs verändern und hoch oder runter setzen. Nur leider betrifft dieser Takt auch den Programmiermodus. Jedenfalls war es nichts mit "programmieren bei höherer Frequenz".
Mal ein Beispiel: der Tiny läuft mit dem 8MHz Oszill. des Tiny 25 ohne gesetztes CKDIV8-Fuse, wobei das CLKPR-Register im Programm auf 1:256 gesetzt wird. Damit müsste der Tiny im "Normalfall" mit 8MHz laufen (gemessen habe ich 8,42MHz) und nach setzen des CLKPR-Registers nur noch mit 31,25kHz (gemessen habe ich 32,1kHz). Soweit so gut. Allerdings sollte das Programmieren bis 8,42MHz/4 = 2,10MHz möglich sein. Es klappt allerdings nur bis zu einem Takt von ungefähr 8kHz! Offensichtlich wird beim Eintritt in den Programmiermodus das CLKPR-Register nicht gelöscht und der Tiny schwingt weiter mit 32kHz
Damit waren meine Hoffnungen bzgl. "es ist doch alles so einfach" dahin.
Eine Lösung hätte ich jetzt mit Hilfe des Watchdog-Timers: Diesen initialisiere ich am Anfang und lasse ihn nach 8s einen Interrupt auslösen. Erst in dessen ISR wird dann das CLKPR-Register gesetzt, so dass ich nach einem RESET eben diese 8s Zeit habe, um mit dem Programmieren zu beginnen. Das klappt auch wunderbar, nur hätte ich es gerne einfacher gehabt.
Für mein RL-Programm würden die Änderungen folgendermaßen aus sehen (stark abgespecktes Listing, welches nur die Änderungen zeigt):
Vielleicht hat ja mal jemand das Bedürfnis einen AVR bis fast zum Stillstand zu verlangsamen. Jedenfalls kann man auf diese Art und Weise den Takt bis auf 500Hz runter bringen - an so einen langsamen Tiny kommt man nämlich normal kaum noch heran, wie AVR Studio einen wissen lässt:
Bild 1.1: Warnung AVR-Studio
Soweit zum CLKPR-Register und viele Grüße,
Thomas(_st)
Hallo zusammen,
ich beginne mal wieder mit einer kurzen Story. Vor ein paar Wochen mit einem befreundeten Cacher verabredet, um an einem seiner Caches eine RL-Stage zu installieren - das RL hatte er schon und war nun dabei etwas Tarnung drumherum zu bauen ... da kam der Anruf: die Tag-/Nachschwelle passt noch nicht (das RL wäre wohl nie in den Tagmodus gegangen) und ob man das nicht anpassen könnte. Also das alte Notebook mit dem alten seriellen Programmer eingepackt und los.
Tja und da saß ich nun. Der auf 128kHz getaktete Tiny ließ sich mit dem Programmer nicht ansprechen (keine Ahnung warum, früher war das kein Problem) und so endete das Ganze damit, dass ein neuer Tiny programmiert wurde und nun mit der originalen Taktfrequenz von ca. 1MHz im Baum hängt.
Aber nach diesen Problemen fiel mir doch wieder ein, was ich schon lange mal ausprobieren und für die RL nutzen wollte: das CLKPR-Register! Dieses Register hat eine ähnliche Aufgabe wie das CKDIV8-Fuse: es teilt den vom Oszillator bereitgestellten Takt runter, bevor daraus der µC-Takt erzeugt wird. Allerdings kommt das CLKPR-Register erst während der Programmlaufzeit zum tragen und es kann den Takt etwas feiner unterteilen (nicht nur 1:8, sondern von 1:2 bis 1:256 in allen Zweierpotenzen).
Hat jemand Erfahrungen mit diesem Register und hat es schon einmal genutzt? Folgende Hoffnung hatte ich damit jedenfalls: man lässt den µC auf den Werkseinstellungen (9,6MHz Oszill. (des Tiny 13) mit gesetzter CKDIV8-Fuse: Takt = 1,2MHz) und teilt den Takt erst im Programm durch Setzen des CLKPR-Registers weiter runter (ginge bis runter auf 37,5kHz). Damit hätte man beim Programmieren einen ordentlich flotten Tiny und während des Programmlaufs einen schön sparsamen. So dachte ich jedenfalls! Aber da hat mir Atmel einen Strich durch die Rechnung gemacht.
Die Experimente zum Runterteilen des Taktes habe ich mit einem Tiny 25 gemacht, da dieser ein CLKO-Pin besitzt, über den man den aktuellen µC-Takt von außen abfragen kann. Zunächst: das CLKPR-Register funktioniert perfekt. Man kann damit wunderbar den Takt während des Programmlaufs verändern und hoch oder runter setzen. Nur leider betrifft dieser Takt auch den Programmiermodus. Jedenfalls war es nichts mit "programmieren bei höherer Frequenz".
Mal ein Beispiel: der Tiny läuft mit dem 8MHz Oszill. des Tiny 25 ohne gesetztes CKDIV8-Fuse, wobei das CLKPR-Register im Programm auf 1:256 gesetzt wird. Damit müsste der Tiny im "Normalfall" mit 8MHz laufen (gemessen habe ich 8,42MHz) und nach setzen des CLKPR-Registers nur noch mit 31,25kHz (gemessen habe ich 32,1kHz). Soweit so gut. Allerdings sollte das Programmieren bis 8,42MHz/4 = 2,10MHz möglich sein. Es klappt allerdings nur bis zu einem Takt von ungefähr 8kHz! Offensichtlich wird beim Eintritt in den Programmiermodus das CLKPR-Register nicht gelöscht und der Tiny schwingt weiter mit 32kHz
Eine Lösung hätte ich jetzt mit Hilfe des Watchdog-Timers: Diesen initialisiere ich am Anfang und lasse ihn nach 8s einen Interrupt auslösen. Erst in dessen ISR wird dann das CLKPR-Register gesetzt, so dass ich nach einem RESET eben diese 8s Zeit habe, um mit dem Programmieren zu beginnen. Das klappt auch wunderbar, nur hätte ich es gerne einfacher gehabt.
Für mein RL-Programm würden die Änderungen folgendermaßen aus sehen (stark abgespecktes Listing, welches nur die Änderungen zeigt):
Code:
[...]
#include <avr/power.h>
[...]
BOOL fInitCLKPR; // Wurde das CLKPR-Register schon initialisiert?
[...]
ISR(SIG_WATCHDOG_TIMEOUT)
{
[...]
if(!fInitCLKPR)
{
clock_prescale_set(clock_div_256); // Hier wird as CLKPR-Register gesetzt
fInitCLKPR = TRUE;
}
[...]
}
[...]
int main (void)
{
[...]
fInitCLKPR = FALSE;
[...]
}

Bild 1.1: Warnung AVR-Studio
Soweit zum CLKPR-Register und viele Grüße,
Thomas(_st)