Hallo,
ich verwende das AVR Xplain und möchte für hohe Datenraten über den UART
den externen Quarz verwenden.
Ich hoffe ich habe es richtig gesehen, dass ein 8MHz Quarz verwendet
wird. Den Code zur Initialisierung habe ich aus folgendem Thread:
Beitrag "Re: XMega Clksystem"
Nun habe ich den Code so erweitert, dass die LEDs leuchten und anzeigen,
wann welcher Punkt erreicht wurde. Der Code ist folgender;
die CPU-Geschwindigkeit ist am Anfang des Programms mit 32MHz
"vorgegeben" (für delay-Berechnungen)
1 | #define F_CPU 32000000UL
|
Zunächst wird auf die interne 32MHz Clocksource gestellt:
1 | CLKSYS_Enable( OSC_RC32MEN_bm );
|
2 | CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );
|
3 | do {} while ( CLKSYS_IsReady( OSC_RC32MRDY_bm ) == 0 );
|
4 | CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC32M_gc );
|
die CPU-Clock-Source soll danach auf PPL gestellt werden. Diese
verwendet als Quelle die externen 8MHz des Quarz und derTakt wird mit
dem Faktor 4 Multipliziert. Somit landet man bei den gewünschten 32MHz.
Der Code dafür ist folgender:
1 | LEDPORT.OUT = 0b11111111;
|
2 | // Oszillator XOSC konfigurieren (2..9MHz, 256 clocks startup time)
|
3 | CLKSYS_XOSC_Config( OSC_FRQRANGE_2TO9_gc,
|
4 | false,
|
5 | OSC_XOSCSEL_XTAL_256CLK_gc );
|
6 | LEDPORT.OUT = 0b11111110;
|
7 | // Oszillator XOSC enable
|
8 | CLKSYS_Enable( OSC_XOSCEN_bm );
|
9 | LEDPORT.OUT = 0b11111100;
|
10 |
|
11 | // Warten bis der Oszillator bereit ist
|
12 | do {} while ( CLKSYS_IsReady( OSC_XOSCRDY_bm ) == 0 );
|
13 | LEDPORT.OUT = 0b11111000;
|
14 |
|
15 | // PLL source ist XOSC, Multiplikator x4
|
16 | CLKSYS_PLL_Config( OSC_PLLSRC_XOSC_gc, 4 );
|
17 | LEDPORT.OUT = 0b11110000;
|
18 |
|
19 | // Enable PLL
|
20 | CLKSYS_Enable( OSC_PLLEN_bm );
|
21 | LEDPORT.OUT = 0b11100000;
|
22 |
|
23 | // Prescalers konfigurieren
|
24 | CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );
|
25 | LEDPORT.OUT = 0b11000000;
|
26 |
|
27 | // Warten bis PLL locked
|
28 | do {} while ( CLKSYS_IsReady( OSC_PLLRDY_bm ) == 0 );
|
29 | LEDPORT.OUT = 0b10000000;
|
30 |
|
31 | // Main Clock Source ist Ausgang von PLL
|
32 | CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_PLL_gc );
|
33 | LEDPORT.OUT = 0b00000000;
|
34 | // Nun ist der System Clock 32MHz !
|
35 |
|
36 | _delay_ms(200);
|
37 | LEDPORT.OUT = 0b11111111;
|
38 | _delay_ms(200);
|
Was auffällt ist, dass beim Schritt 2 (warten auf das Okay vom
Quarz-erzeugten Takt) die LEDs häufig einige ms bis manchmal hin zu
einer knappen Sekunde "stehen" bleiben. Nachdem die Clock Source
umgestellt wurde passiert fast gar nix mehr. Das togglen der LEDs zum
Schluss passiert meistens erst nach sehr vielen Sekunden.
Meine Vermutung ist, dass der Quarz nicht richtig anschwingt aber ich
kann mir auch vorstellen, dass der Quarz bei der Produktion getestet
wurde. Könnt Ihr einen Fehler im Code feststellen? Habe ich irgendwas
vergessen?
Nachtrag:
Ich habe leider kein Kältespray aber ich kann folgendes Verhalten
feststellen:
Mit einem Fön erwärmt beginnen bei nachfolgendem Code die LEDs immer
schneller zu togglen umso wärmer der Quarz ist. Bei hohen Temperaturen
ist die Frequenz relativ hoch (ca. 10-20Hz). Nach dem Abkühlen mit Eis
togglen die LEDs nur noch alle paar Sekunden oder gar nicht mehr.
1 | while (1)
|
2 | {
|
3 | LEDPORT.OUTTGL = 0b11111111;
|
4 | }
|
Mit freundlichen Grüßen
Elektrofreak