Allgemein
Die Atmega*U besitzen zusätzlich zu den gewohnten Taktquellen eine PLL. Diese rastet in die gewählte Taktfrequenz ein und dient dazu, die 48MHz für den USB-Takt zu erzeugen.
Laut Datenblatt wird der Chip mit mit aktiviertem internen RC-Oszillator ausgeliefert. Da aber auch bereits ein Bootloader für USB auf den Chips mitgeliefert wird schaltet dieser praktischerweise die Taktquelle auf den externen Quartz um. Das bedeutet, dass der Atmega*U2 nicht zuverlässig (bzw. gar nicht) ohne 8MHz bzw. 16MHz Oszillator anläuft.
Warum das Ganze?
Wie oben schon geschrieben „schaltet der Bootloader die Taktquelle um“. Wie funktioniert das denn jetzt? Das ist definitiv neu im Vergleich zu den standard-Atmegas. Prinzipiell ist diese Neuerung essentiell und hat einige gute Gründe:
- Der Atmega*U kann über USB programmiert werden, allerdings nur der Speicher, die Fuses können von FLIP nicht verändert werden. Ohne über die Software einstellbare Taktquellen könnte man also nicht zwischen den verschiedenen wählen.
- Der Atmega*U kann theoretisch vom USB in den Sleep-Mode geschickt werden (Ruhemodus des PC, …). Dann darf der Controller nur noch einen geringen Strom aus der USB-Leitung ziehen. Dafür kann zB die PLL und der externe Takt abgeschalten und der Controller über den internen RC-Oszillator gespeist werden.
Register
Folgende Register stehen zur Verfügung:
Name | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
CLKSEL0 | RCSUT1 | RCSUT0 | EXSUT1 | EXSUT0 | RCE | EXTE | - | CLKS |
CLKSEL1 | RCCKSE L3 | RCCKSE L2 | RCCKSE L1 | RCCKSE L0 | EXCKSE L3 | EXCKSE L2 | EXCKSE L1 | EXCKSE L0 |
CLKSTA | - | - | - | - | - | - | RCON | EXTON |
OSCCAL | CAL7 | CAL6 | CAL5 | CAL4 | CAL3 | CAL2 | CAL1 | CAL0 |
CLKPR | CLKPCE | - | - | - | CLKPS3 | CLKPS2 | CLKPS1 | CLKPS0 |
PLLCSR | - | - | - | DIV5 | DIV3 | PINDIV | PLLE | PLOCK |
Umschalten zwischen Taktquellen
Unabhängig von den Fuses kann man jetzt zwischen den Taktquellen umschalten. Man hat folgende Quellen zur Auswahl
- RC Oszillator
- Externe Taktquelle
Für das Umschalten ist Bit0 im CLKSEL0 Register zuständig, 0 wählt den internen RC Oszillator, 1 wählt die externe Taktquelle:
CLKSEL0 |= (1<<CLKS); // Diese Zeile wählt die externe Taktquelle
CLKSEL0 &= ~(1<<CLKS); // Diese Zeile wählt den internen RC-Oszillator
Sollte diese Taktquelle aber gerade schlafen/deaktiviert sein hat man ein Problem. Man sollte also vorher sicherstellen, dass die Taktquelle auch eingeschalten ist:
CLKSEL0 |= (1<<RCE); // Diese Zeile schaltet den RC Oszillator ein
CLKSEL0 |= (1<<EXTE); // Diese Zeile schaltet die externe Taktquelle ein
CLKSEL0 |= (1<<EXTE) | (1<<CLKS); // Diese Zeile schaltet die externe Taktquelle in und wählt sie als CPU-Takt