Kampis Elektroecke

XMega – Taktsystem

XMega Blockdiagramm

Der XMega besitzt, im Gegensatz zu den AVR8 Mikrocontrollern, ein sehr umfangreiches System um den Systemtakt zu generieren. Es werden folgende Taktquellen angeboten:

  • Ein interner 2 MHz Oszillator (Standardtaktquelle)
  • Ein interner 32 MHz Oszillator
  • Einen ULP Oszillator für den Watchdog Timer
  • Eine PLL mit einem Multiplikator von 1 – 31
  • Ein interner 32 kHz Oszillator
  • Ein externes 0,4 MHz – 16 MHz Quarz
  • Ein externes 32 kHz Quarz
  • Ein beliebiger externer Taktgeber

Weiterhin kann der erzeugte Systemtakt mit Hilfe eines Prescalers um bis zu 2048 reduziert werden. Die Funktionsweise des Taktsystems wird im Datenblatt mit einem ausführlichen Blockdiagramm beschrieben.

Anders als beim ATtiny/ATmega kann man bei einem XMega den Takt nicht mittels Fusebits einstellen und nach einem Reset ist automatisch der interne 2 MHz Oszillator aktiv.

Verwenden einer internen Taktquelle:

Im ersten Beispiel soll der 32 MHz Oszillator statt des 2 MHz Oszillators verwendet werden. Dazu muss der 32 MHz Oszillator aktiviert werden, indem das RC32MEN-Bit im CTRL-Register des Oszillator-Moduls gesetzt wird:

OSC.CTRL |= OSC_RC32MEN_bm;
while(!(OSC.STATUS & OSC_RC32MRDY_bm));

Durch die Schleife wartet das Programm solange bis das RC32MRDY-Bit im STATUS-Register gesetzt und der Oszillator eingeschwungen ist. Der Oszillator ist jetzt aktiviert und kann als Taktquelle verwendet werden. Die aktuelle Taktquelle wird über das CTRL-Register des Clock-Moduls eingestellt.

Dieses Register ist mit einem Konfigurationsschutz versehen, was bedeutet, dass zuerst ein spezieller Wert in das CCP-Register des Mikrocontrollers geschrieben werden muss, bevor das Register verändert werden kann.

Nach dem Beschreiben des CCP-Registers hat die Software dann 4 Taktzyklen Zeit um ein geschütztes Register zu beschreiben. Danach wird die Entsperrung aufgehoben. Zuerst wird also das CCP-Register beschrieben:

CCP = CCP_IOREG_gc;

Und im nächsten Schritt kann dann der interne 32 MHz Oszillator als Taktquelle ausgewählt werden:

CLK.CTRL = CLK_SCLKSEL_RC32M_gc;

Achtung:

Ohne Optimierung ist der Codeschnipsel

CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_RC32M_gc;

zu langsam und benötigt mehr als 4 Taktzyklen (siehe hier). Es ist daher empfehlenswert mindestens -O1 als Optimierung zu verwenden oder auf Inline-Assembler auszuweichen.


Ab jetzt wird die AVR-CPU mit einem 32 MHz Takt versorgt.

Um auf den 2 MHz Oszillator zu wechseln, muss das die ganze Prozedur wiederholt werden, wobei das Bitmuster von OSC_RC32MEN_bm in OSC_R32MEN_bm geändert werden muss.

Eine externe Taktquelle verwenden:

Eine externe Taktquelle wird ähnlich eingestellt wie die interne Taktquelle. Es müssen nur die Bits im CTRL-Register der System Clock und des Oszillators umgeändert werden. Zusätzlich muss im XOSCCTRL-Register noch die Frequenz des externen Taktes sowie die Start-up Time eingestellt werden.

Für einen externen 16 MHz Quarz mit einer Start-up Time von 16 Taktzyklen sieht der Codeschnipsel folgendermaßen aus:

OSC_XOSCCTRL = OSC_XOSCSEL_XTAL_16KCLK_gc | OSC_FRQRANGE_12TO16_gc;
OSC.CTRL |= OSC_XOSCEN_bm;
while(!(OSC.STATUS & OSC_XOSCRDY_bm));
CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_XOSC_gc;

Konfigurieren der PLL:

Der XMega besitzt eine interne PLL mit der der Systemtakt um den Faktor 1 – 31 erhöht werden kann. Bevor die PLL genutzt werden kann, muss die Taktquelle, die den Eingangstakt für die PLL liefert, richtig eingestellt und initialisiert werden.

Im nächsten Beispiel soll der interne 32 MHz Takt mit Hilfe der PLL erhöht werden. Als erstes muss der interne Oszillator aktiviert werden.

OSC.CTRL |= OSC_RC32MEN_bm;
while(!(OSC.STATUS & OSC_RC32MRDY_bm));

Anschließend muss die PLL über das PLLCTRL-Register konfiguriert werden. Über dieses Register wird die Taktquelle, der Multiplikator und ein optionaler Divisor für den Ausgangstakt eingestellt.

Als Multiplikator verwende ich in diesem Beispiel den Wert 0x06.

OSC.PLLCTRL = OSC_PLLSRC_RC32M_gc | 0x06;

Vorsicht:

Wer sich das oben stehende Bild vom Clock System aufmerksam angeschaut hat, wird sicher auch schon festgestellt haben, dass der interne 32 MHz Takt erst durch 4 geteilt wird, bevor er in den Eingangsmultiplexer der PLL geht. Dies sorgt für eine feinere Auflösung beim Einstellen des Taktes in höheren Bereichen. 


Danach wird die PLL aktiviert und darauf gewartet, dass die PLL eingeschwungen ist.

OSC.CTRL |= OSC_PLLEN_bm;
while(!(OSC.STATUS & OSC_PLLRDY_bm));

Und zum Abschluss wird die PLL dann als Taktquelle ausgewählt:

CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_PLL_gc;

Von nun an arbeitet die CPU mit einer einem Systemtakt von 48 MHz.

Sämtliche Beispielcodes sind in meinem GitHub-Repository verfügbar.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert