So dachte ich mir das und es Funktioniert auch Spitze im simulator, aber irgendwie sehe ich an der Blinkenden LED das hier nur 2MHz im spiel sind und nicht 32MHz. 100nF Kondensatoren habe ich an allen VCC/GND Eingängen. Gibts noch irgendwas was man beachten muss? void config_osc(void) { OSC.CTRL |= OSC_RC32MEN_bm; while (!(OSC.STATUS & OSC_RC32MRDY_bm)) {}; CCP |= CCP_IOREG_gc; CLK.CTRL = CLK_SCLKSEL_RC32M_gc; DFLLRC32M.CTRL = DFLL_ENABLE_bm; }
Also am Clockout Pin sehe ich klare 2MHz, irgend warum springt er scheinbar sofort nach dem aktivieren wieder zurueck auf die 2MHz, aber warum?
Also ich verstehs nicht, clockout sind immmer 2MHz und das lustige ist noch das das Blinken der LED in main.c langsammer ist als in der myclock.c main.c:
1 | #define F_CPU 32000000
|
2 | #define BAUDRATE 115200
|
3 | #define LED_PORT PORTB
|
4 | #define LED_RED_bp 0
|
5 | |
6 | |
7 | #include <avr/io.h> |
8 | #include <util/delay.h> |
9 | #include <avr/interrupt.h> |
10 | |
11 | int main(void) |
12 | {
|
13 | PORTB.DIR |= (1 << 0) | (1 << 1); |
14 | PORTB.OUT |= (1 << 0) | (1 << 1); |
15 | |
16 | //CLK out
|
17 | PORTC.DIR = (1 << 7); |
18 | PORTCFG.CLKEVOUT= PORTCFG_CLKOUT0_bm; |
19 | |
20 | sync_osc(); |
21 | |
22 | while(1) |
23 | {
|
24 | |
25 | for (uint8_t i=0; i<200; i++) |
26 | {
|
27 | PORTB.OUTTGL = (1<<PIN0); |
28 | _delay_ms(200); |
29 | PORTB.OUTTGL = (1<<PIN0); |
30 | _delay_ms(200); |
31 | }
|
32 | }
|
33 | }
|
myclock.c:
1 | #include <avr/io.h> |
2 | #include <util/delay.h> |
3 | #include <avr/interrupt.h> |
4 | #define F_CPU 32000000
|
5 | |
6 | void sync_osc(void) { |
7 | OSC.CTRL |= OSC_RC32MEN_bm; |
8 | while (!(OSC.STATUS & OSC_RC32MRDY_bm)) {}; |
9 | CCP |= CCP_IOREG_gc; |
10 | CLK.CTRL = CLK_SCLKSEL_RC32M_gc; |
11 | |
12 | DFLLRC32M.CTRL = DFLL_ENABLE_bm; |
13 | for (uint8_t i=0; i<200; i++) |
14 | {
|
15 | PORTB.OUTTGL = (1<<PIN1); |
16 | _delay_ms(200); |
17 | PORTB.OUTTGL = (1<<PIN1); |
18 | _delay_ms(200); |
19 | }
|
20 | }
|
ich habe es wie unten beschrieben eingestellt. http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial#clock_einstellungen Damit läuft mein XMega mit 32MHz.
Danke für die Antwort habs auch probiert, ich glaube langsam ich hab hier irgendwas an der Beschaltung falsch.
1 | #define F_CPU 32000000
|
2 | #define BAUDRATE 115200
|
3 | #define LED_PORT PORTB
|
4 | #define LED_RED_bp 0
|
5 | |
6 | #include <avr/io.h> |
7 | #include <util/delay.h> |
8 | #include <avr/interrupt.h> |
9 | |
10 | int main(void) |
11 | {
|
12 | PORTB.DIR |= (1 << 0) | (1 << 1); |
13 | PORTB.OUT |= (1 << 0) | (1 << 1); |
14 | |
15 | //CLK out
|
16 | PORTC.DIR = (1 << 7); |
17 | PORTCFG.CLKEVOUT= PORTCFG_CLKOUT0_bm; |
18 | |
19 | /*Oscillator auf 32Mhz einstellen PIN1 = OSC_RC32MEN wird gesetzt */
|
20 | OSC.CTRL |= 0x02; |
21 | /*Wenn Oscillator stabil wird das Flag RC32MRDY
|
22 | * gesetzt und 32Mhz können benutzt werden*/
|
23 | while(!(OSC.STATUS & OSC_RC32MRDY_bm)); |
24 | /*I/O Protection*/
|
25 | CCP = 0xD8; |
26 | /*Clock auf 32Mhz einstellen*/
|
27 | CLK.CTRL = 0x01; |
28 | {
|
29 | PORTB.OUTTGL = (1<<PIN1); |
30 | _delay_ms(200); |
31 | PORTB.OUTTGL = (1<<PIN1); |
32 | _delay_ms(200); |
33 | }
|
34 | |
35 | while(1) |
36 | {
|
37 | |
38 | for (uint8_t i=0; i<100; i++) |
39 | {
|
40 | PORTB.OUTTGL = (1<<PIN0); |
41 | _delay_ms(200); |
42 | PORTB.OUTTGL = (1<<PIN0); |
43 | _delay_ms(200); |
44 | }
|
45 | }
|
46 | }
|
zudem scheint mir das hier falsch zu sein: /*Clock auf 32Mhz einstellen*/ CLK.CTRL = 0x01; Musste das nicht 0x02 sein?
Hallo, habe deinen Code mal installiert und getestet. So funktioniert es bei mir wunderbar! Mit Oszi kontrolliert. 2 Mhz //system_clocks_init() auskommentiert #define F_CPU 32000000 #define BAUDRATE 115200 #define LED_PORT PORTB #define LED_RED_bp 0 #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> void system_clocks_init(void); int main(void) { system_clocks_init(); PORTC.DIR = (1 << 7); PORTCFG.CLKEVOUT= PORTCFG_CLKOUT0_bm; PORTB.DIR |= (1 << 0) | (1 << 1); PORTB.OUT |= (1 << 0) | (1 << 1); while(1) { for (uint8_t i=0; i<100; i++) { PORTB.OUTTGL = (1<<PIN0); _delay_ms(200); PORTB.OUTTGL = (1<<PIN0); _delay_ms(200); } } } // System Clocks initialization void system_clocks_init(void) { /*Oscillator auf 32Mhz einstellen PIN1 = OSC_RC32MEN wird gesetzt */ OSC.CTRL |= 0x02; /*Wenn Oscillator stabil wird das Flag RC32MRDY * gesetzt und 32Mhz können benutzt werden*/ while(!(OSC.STATUS & OSC_RC32MRDY_bm)); /*I/O Protection*/ CCP = 0xD8; /*Clock auf 32Mhz einstellen*/ CLK.CTRL = 0x01; } Gruß xmega
Vielen Dank für das testen!! Also bei mir funzt auch das nicht, hast du auch einen ATxmega32A4 genommen? Irgend ein besonderes Board oder Beschaltung?
besteht eventuell die Möglichkeit mal deine .hex datei zu bekommen? dann könnte ich die hier direkt einspielen.
Hallo, einfaches Board Atxmega32A4 http://www.wiki.elektronik-projekt.de/embedit/smd_adapter/tqfp44_mlf44_ Gruß xmega
läuft nun auch hier auf 32MHz unglaublich... das muss also was mit dem AVR Studio zu tun haben und der .hex die das ding erstellt. Die Ausgabe vom AVRStudio 5 http://nopaste.php-quake.net/145092
Man muss im AVR Studio5.1 die Code-Optimierung anpassen da nach dem CCP nur 4 Takte Zeit sind die Settings ins CLK.CTRL zu schreiben. Dazu im Solution Explorer auf Projekt rechts klicken -> Properties -> AVR/GNU C Compiler -> Optimization -> Optimization Level: -O2 Grüße, meHli
ich benutze nachfolgende Funktion zum Schreiben solcher Register. Damit hat sich das mit dem Rumfummeln an den Complierswitches. Gruß hagen
1 | void CCP_Write(volatile uint8_t* address, uint8_t value) { |
2 | |
3 | AVR_ENTER_CRITICAL_REGION(); |
4 | volatile uint8_t* tmpAddr = address; |
5 | #ifdef RAMPZ
|
6 | RAMPZ = 0; |
7 | #endif
|
8 | asm volatile( |
9 | "movw r30, %0" "\n\t" |
10 | "ldi r16, %2" "\n\t" |
11 | "out %3, r16" "\n\t" |
12 | "st Z, %1" "\n\t" |
13 | :
|
14 | : "r" (tmpAddr), "r" (value), "M" (CCP_IOREG_gc), "i" (&CCP) |
15 | : "r16", "r30", "r31" |
16 | );
|
17 | |
18 | AVR_LEAVE_CRITICAL_REGION(); |
19 | }
|
Einstellen des Taktsystems:
1 | // Taktsystem konfigurieren
|
2 | // externen 16MHz Quarz einschalten
|
3 | OSC.XOSCCTRL = OSC_XOSCSEL_XTAL_16KCLK_gc | OSC_FRQRANGE_12TO16_gc;// | OSC_X32KLPM_bm; |
4 | OSC.CTRL |= OSC_XOSCEN_bm; |
5 | while (!(OSC.STATUS & OSC_XOSCRDY_bm)); |
6 | // PLL Source = 16MHz ext. Quarz * 8 = 128 MHz
|
7 | OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | (8 << OSC_PLLFAC_gp); |
8 | OSC.CTRL |= OSC_PLLEN_bm; |
9 | while (!(OSC.STATUS & OSC_PLLRDY_bm)); |
10 | // CLK-Prescaler A/1 B/2 C/2 -> 128MHz -> 64MHz -> 32MHz
|
11 | CCP_Write(&CLK.PSCTRL, CLK_PSADIV_1_gc | CLK_PSBCDIV_2_2_gc); |
12 | // PLL nun als Systemclock auswählen
|
13 | CCP_Write(&CLK.CTRL, CLK_SCLKSEL_PLL_gc); |
14 | // 2MHz und 32MHz RC abschalten
|
15 | OSC.CTRL &= ~(OSC_RC32MEN_bm | OSC_RC2MEN_bm | OSC_RC32KEN_bm); |
16 | // nun CLK Einstellungen schützen
|
17 | CCP_Write(&CLK.LOCK, CLK_LOCK_bm); |
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.