ATxmega32A4 Umschaltung von 2MHz auf 32MHz

OP #2484357
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;
}
OP #2485353
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
}
OP #2485386
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
}
#2485503
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
Gast #2559358
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
#2559454
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);

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren