Forum: Mikrocontroller und Digitale Elektronik ATxmega32A4 Umschaltung von 2MHz auf 32MHz


von Simon M. (simon2)


Lesenswert?

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;
}

von Simon M. (simon2)


Lesenswert?

Also am Clockout Pin sehe ich klare 2MHz,
irgend warum springt er scheinbar sofort nach dem aktivieren wieder 
zurueck auf die 2MHz, aber warum?

von Simon M. (simon2)


Lesenswert?

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
}

von Lucky (Gast)


Lesenswert?

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.

von Simon M. (simon2)


Lesenswert?

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
}

von Simon M. (simon2)


Lesenswert?

zudem scheint mir das hier falsch zu sein:

   /*Clock auf 32Mhz einstellen*/
   CLK.CTRL = 0x01;

Musste das nicht 0x02 sein?

von Gerhard G. (xmega)


Lesenswert?

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

von Simon M. (simon2)


Lesenswert?

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?

von Simon M. (simon2)


Lesenswert?

besteht eventuell die Möglichkeit mal deine .hex datei zu bekommen?
dann könnte ich die hier direkt einspielen.

von Gerhard G. (xmega)


Angehängte Dateien:

Lesenswert?

Hallo,

einfaches Board Atxmega32A4

http://www.wiki.elektronik-projekt.de/embedit/smd_adapter/tqfp44_mlf44_


Gruß xmega

von Simon M. (simon2)


Lesenswert?

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

von meHli (Gast)


Lesenswert?

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

von Hagen R. (hagen)


Lesenswert?

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
Noch kein Account? Hier anmelden.