[FRDM-KL25Z] Ustawienie zegara na 48MHz

Pytania dotyczące problemów ze zrozumieniem kart katalogowych, not aplikacyjnych dla mkrokontrolerów ARM firmy Freescale, rozwiązania układowe z zastosowaniem tych mikrokontrolerów.
Awatar użytkownika
Nefarious19
Newb
Newb
Posty: 80
Rejestracja: sobota 02 sty 2016, 20:45

[FRDM-KL25Z] Ustawienie zegara na 48MHz

Postautor: Nefarious19 » poniedziałek 21 lis 2016, 21:20

Witam panowie,

Piszę do Was ponieważ próbuje uruchomić 48MHz oscylator z zewnętrznego kwarca na tej płytce i niestety nie wiem czy to udało mi się uczynić. Oto kod:

Kod: Zaznacz cały

/**
*****************************************************************************
**
**  File        : main.c
**
**  Abstract    : main function.
**
**  Functions   : main
**
**  Environment : Atollic TrueSTUDIO(R)
**
**  Distribution: The file is distributed "as is", without any warranty
**                of any kind.
**
**  (c)Copyright Atollic AB.
**  You may use this file as-is or modify it according to the needs of your
**  project. This file may only be built (assembled or compiled and linked)
**  using the Atollic TrueSTUDIO(R) product. The use of this file together
**  with other tools than Atollic TrueSTUDIO(R) is not permitted.
**
*****************************************************************************
*/

#include "mcu.h"



int main(void)
{
   //oscillator configuration
   OSC0->CR |= (1<<OSC_CR_ERCLKEN_SHIFT) | (1<<OSC_CR_EREFSTEN_SHIFT);
   MCG->C2 &= ~(1<<MCG_C2_HGO0_SHIFT);
   MCG->C2 |= (1<<MCG_C2_RANGE0_SHIFT) | (1<<MCG_C2_EREFS0_SHIFT);
   MCG->C1 |= (2<<MCG_C1_CLKS_SHIFT) | (0b11<<MCG_C1_FRDIV_SHIFT);
   MCG->C1 &= ~(1<<MCG_C1_IREFS_SHIFT);

   while(!((MCG->S)&(1<<MCG_S_OSCINIT0_SHIFT)));
   while(((MCG->S)&(1<<MCG_S_IREFST_SHIFT)));
   while(!(((MCG->S)&(2<<MCG_S_CLKST_SHIFT))==(2<<MCG_S_CLKST_SHIFT)));

   MCG->C5 |= (4<<MCG_C5_PRDIV0_SHIFT);
   MCG->C6 &= ~(0b00011111);

   MCG->C2 |= (1<<MCG_C2_LP_SHIFT);
   MCG->C6 = 0x40;
   MCG->C2 &= ~(1<<MCG_C2_LP_SHIFT);

   while(!((MCG->S)&(1<<MCG_S_PLLST_SHIFT)));
   while(!((MCG->S)&(1<<MCG_S_LOCK0_SHIFT)));

   MCG->C1 = 0x10;
   while( !((MCG->S & (3<<MCG_S_CLKST_SHIFT)) == (3<<MCG_S_CLKST_SHIFT)) );

   SIM->CLKDIV1 &= ~((1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<16)|(1<<17)|(1<<18));


   SIM->SCGC5 |= (1<<10);
   SIM->SCGC5 |= (1<<12);


//    PORTB->PCR[19] |= (1<<8);
    PORTB->PCR[18] |= (1<<8);
//    PORTD->PCR[1] |= (1<<8);
//    PTB->PDDR |= (1<<19);
//    PTB->PCOR |= (1<<19);
    PTB->PDDR |= (1<<18);
    PTB->PCOR |= (1<<18);
//    PTD->PDDR |= (1<<1);
//    PTD->PCOR |= (1<<1);


    uint32_t delay = 50000;

    while (1)
    {
         while(delay--);
         delay = 500000;
         PTB->PSOR |= (1<<18);
         while(delay--);
         delay = 500000;
         PTB->PCOR |= (1<<18);

    }
    return 0;
}





Dioda sobie miga co około 200ms, obojętnie czy zostawie w kodzie ustawianie zegara czy nie. Ma ktoś jakiś sprawdzony kod bym mógł sobie porównać?
Plany na przyszłość: C, C++, C#

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1168
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: [FRDM-KL25Z] Ustawienie zegara na 48MHz

Postautor: Antystatyczny » poniedziałek 21 lis 2016, 21:24

Ja zawsze korzystałem z tego, co mi wygenerował Atollic w pliku system_MKL25Z4.c:

Kod: Zaznacz cały

/*

** ###################################################################

**     Processor:           MKL25Z128VLK4

**     Compilers:           ARM Compiler

**                          Freescale C/C++ for Embedded ARM

**                          GNU C Compiler

**                          IAR ANSI C/C++ Compiler for ARM

**

**     Reference manual:    KL25RM, Rev.1, Jun 2012

**     Version:             rev. 1.1, 2012-06-21

**

**     Abstract:

**         Provides a system configuration function and a global variable that

**         contains the system frequency. It configures the device and initializes

**         the oscillator (PLL) that is part of the microcontroller device.

**

**     Copyright: 2012 Freescale Semiconductor, Inc. All Rights Reserved.

**

**     http:                 www.freescale.com

**     mail:                 support@freescale.com

**

**     Revisions:

**     - rev. 1.0 (2012-06-13)

**         Initial version.

**     - rev. 1.1 (2012-06-21)

**         Update according to reference manual rev. 1.

**

** ###################################################################

*/



/**

 * @file MKL25Z4

 * @version 1.1

 * @date 2012-06-21

 * @brief Device specific configuration file for MKL25Z4 (implementation file)

 *

 * Provides a system configuration function and a global variable that contains

 * the system frequency. It configures the device and initializes the oscillator

 * (PLL) that is part of the microcontroller device.

 */



#include <stdint.h>

#include "MKL25Z4.h"



#define DISABLE_WDOG    1



#define CLOCK_SETUP     1

/* Predefined clock setups

   0 ... Multipurpose Clock Generator (MCG) in FLL Engaged Internal (FEI) mode

         Reference clock source for MCG module is the slow internal clock source 32.768kHz

         Core clock = 41.94MHz, BusClock = 13.98MHz

   1 ... Multipurpose Clock Generator (MCG) in PLL Engaged External (PEE) mode

         Reference clock source for MCG module is an external crystal 8MHz

         Core clock = 48MHz, BusClock = 24MHz

   2 ... Multipurpose Clock Generator (MCG) in Bypassed Low Power External (BLPE) mode

         Core clock/Bus clock derived directly from an external crystal 8MHz with no multiplication

         Core clock = 8MHz, BusClock = 8MHz

*/



/*----------------------------------------------------------------------------

  Define clock source values

 *----------------------------------------------------------------------------*/

#if (CLOCK_SETUP == 0)

    #define CPU_XTAL_CLK_HZ                 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */

    #define CPU_INT_SLOW_CLK_HZ             32768u   /* Value of the slow internal oscillator clock frequency in Hz  */

    #define CPU_INT_FAST_CLK_HZ             4000000u /* Value of the fast internal oscillator clock frequency in Hz  */

    #define DEFAULT_SYSTEM_CLOCK            41943040u /* Default System clock value */

#elif (CLOCK_SETUP == 1)

    #define CPU_XTAL_CLK_HZ                 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */

    #define CPU_INT_SLOW_CLK_HZ             32768u   /* Value of the slow internal oscillator clock frequency in Hz  */

    #define CPU_INT_FAST_CLK_HZ             4000000u /* Value of the fast internal oscillator clock frequency in Hz  */

    #define DEFAULT_SYSTEM_CLOCK            48000000u /* Default System clock value */

#elif (CLOCK_SETUP == 2)

    #define CPU_XTAL_CLK_HZ                 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */

    #define CPU_INT_SLOW_CLK_HZ             32768u   /* Value of the slow internal oscillator clock frequency in Hz  */

    #define CPU_INT_FAST_CLK_HZ             4000000u /* Value of the fast internal oscillator clock frequency in Hz  */

    #define DEFAULT_SYSTEM_CLOCK            8000000u /* Default System clock value */

#endif /* (CLOCK_SETUP == 2) */





/* ----------------------------------------------------------------------------

   -- Core clock

   ---------------------------------------------------------------------------- */



uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;



/* ----------------------------------------------------------------------------

   -- SystemInit()

   ---------------------------------------------------------------------------- */



void SystemInit (void) {

#if (DISABLE_WDOG)

  /* Disable the WDOG module */

  /* SIM_COPC: COPT=0,COPCLKS=0,COPW=0 */

  SIM->COPC = (uint32_t)0x00u;

#endif /* (DISABLE_WDOG) */

#if (CLOCK_SETUP == 0)

  /* SIM->CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=2,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */

  SIM->CLKDIV1 = (uint32_t)0x00020000UL; /* Update system prescalers */

  /* Switch to FEI Mode */

  /* MCG->C1: CLKS=0,FRDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */

  MCG->C1 = (uint8_t)0x06U;

  /* MCG_C2: LOCRE0=0,??=0,RANGE0=0,HGO0=0,EREFS0=0,LP=0,IRCS=0 */

  MCG->C2 = (uint8_t)0x00U;

  /* MCG->C4: DMX32=0,DRST_DRS=1 */

  MCG->C4 = (uint8_t)((MCG->C4 & (uint8_t)~(uint8_t)0xC0U) | (uint8_t)0x20U);

  /* OSC0->CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */

  OSC0->CR = (uint8_t)0x80U;

  /* MCG->C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */

  MCG->C5 = (uint8_t)0x00U;

  /* MCG->C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */

  MCG->C6 = (uint8_t)0x00U;

  while((MCG->S & MCG_S_IREFST_MASK) == 0x00U) { /* Check that the source of the FLL reference clock is the internal reference clock. */

  }

  while((MCG->S & 0x0CU) != 0x00U) {    /* Wait until output of the FLL is selected */

  }

#elif (CLOCK_SETUP == 1)

  /* SIM->SCGC5: PORTA=1 */

  SIM->SCGC5 |= (uint32_t)0x0200UL;     /* Enable clock gate for ports to enable pin routing */

  /* SIM->CLKDIV1: OUTDIV1=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=1,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */

  SIM->CLKDIV1 = (uint32_t)0x10010000UL; /* Update system prescalers */

  /* PORTA->PCR18: ISF=0,MUX=0 */

  PORTA->PCR[18] &= (uint32_t)~0x01000700UL;

  /* PORTA->PCR19: ISF=0,MUX=0 */

  PORTA->PCR[19] &= (uint32_t)~0x01000700UL;

  /* Switch to FBE Mode */

  /* OSC0->CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=1,SC4P=0,SC8P=0,SC16P=1 */

  OSC0->CR = (uint8_t)0x89U;

  /* MCG->C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */

  MCG->C2 = (uint8_t)0x24U;

  /* MCG->C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */

  MCG->C1 = (uint8_t)0x9AU;

  /* MCG->C4: DMX32=0,DRST_DRS=0 */

  MCG->C4 &= (uint8_t)~(uint8_t)0xE0U;

  /* MCG->C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=1 */

  MCG->C5 = (uint8_t)0x01U;

  /* MCG->C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */

  MCG->C6 = (uint8_t)0x00U;

  while((MCG->S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */

  }

  while((MCG->S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */

  }

  /* Switch to PBE Mode */

  /* MCG->C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0 */

  MCG->C6 = (uint8_t)0x40U;

  while((MCG->S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */

  }

  while((MCG->S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */

  }

  /* Switch to PEE Mode */

  /* MCG->C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */

  MCG->C1 = (uint8_t)0x1AU;

  while((MCG->S & 0x0CU) != 0x0CU) {    /* Wait until output of the PLL is selected */

  }

#elif (CLOCK_SETUP == 2)

  /* SIM->SCGC5: PORTA=1 */

  SIM->SCGC5 |= (uint32_t)0x0200UL;     /* Enable clock gate for ports to enable pin routing */

  /* SIM->CLKDIV1: OUTDIV1=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,OUTDIV4=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */

  SIM->CLKDIV1 = (uint32_t)0x00000000UL; /* Update system prescalers */

  /* PORTA->PCR18: ISF=0,MUX=0 */

  PORTA->PCR[18] &= (uint32_t)~0x01000700UL;

  /* PORTA->PCR19: ISF=0,MUX=0 */

  PORTA->PCR[19] &= (uint32_t)~0x01000700UL;

  /* Switch to FBE Mode */

  /* OSC0->CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=1,SC4P=0,SC8P=0,SC16P=1 */

  OSC0->CR = (uint8_t)0x89U;

  /* MCG->C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */

  MCG->C2 = (uint8_t)0x24U;

  /* MCG->C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */

  MCG->C1 = (uint8_t)0x9AU;

  /* MCG->C4: DMX32=0,DRST_DRS=0 */

  MCG->C4 &= (uint8_t)~(uint8_t)0xE0U;

  /* MCG->C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */

  MCG->C5 = (uint8_t)0x00U;

  /* MCG->C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */

  MCG->C6 = (uint8_t)0x00U;

  while((MCG->S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */

  }

  while((MCG->S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */

  }

  /* Switch to BLPE Mode */

  /* MCG->C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=1,IRCS=0 */

  MCG->C2 = (uint8_t)0x26U;

  while((MCG->S & 0x0CU) != 0x08U) {    /* Wait until external reference clock is selected as MCG output */

  }

#endif /* (CLOCK_SETUP == 2) */

}



/* ----------------------------------------------------------------------------

   -- SystemCoreClockUpdate()

   ---------------------------------------------------------------------------- */



void SystemCoreClockUpdate (void) {

  uint32_t MCGOUTClock;                                                        /* Variable to store output clock frequency of the MCG module */

  uint8_t Divider;



  if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x0u) {

    /* Output of FLL or PLL is selected */

    if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u) {

      /* FLL is selected */

      if ((MCG->C1 & MCG_C1_IREFS_MASK) == 0x0u) {

        /* External reference clock is selected */

        MCGOUTClock = CPU_XTAL_CLK_HZ;                                       /* System oscillator drives MCG clock */

        Divider = (uint8_t)(1u << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT));

        MCGOUTClock = (MCGOUTClock / Divider);  /* Calculate the divided FLL reference clock */

        if ((MCG->C2 & MCG_C2_RANGE0_MASK) != 0x0u) {

          MCGOUTClock /= 32u;                                                  /* If high range is enabled, additional 32 divider is active */

        } /* ((MCG->C2 & MCG_C2_RANGE0_MASK) != 0x0u) */

      } else { /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x0u)) */

        MCGOUTClock = CPU_INT_SLOW_CLK_HZ;                                     /* The slow internal reference clock is selected */

      } /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x0u)) */

      /* Select correct multiplier to calculate the MCG output clock  */

      switch (MCG->C4 & (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) {

        case 0x0u:

          MCGOUTClock *= 640u;

          break;

        case 0x20u:

          MCGOUTClock *= 1280u;

          break;

        case 0x40u:

          MCGOUTClock *= 1920u;

          break;

        case 0x60u:

          MCGOUTClock *= 2560u;

          break;

        case 0x80u:

          MCGOUTClock *= 732u;

          break;

        case 0xA0u:

          MCGOUTClock *= 1464u;

          break;

        case 0xC0u:

          MCGOUTClock *= 2197u;

          break;

        case 0xE0u:

          MCGOUTClock *= 2929u;

          break;

        default:

          break;

      }

    } else { /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u)) */

      /* PLL is selected */

      Divider = (1u + (MCG->C5 & MCG_C5_PRDIV0_MASK));

      MCGOUTClock = (uint32_t)(CPU_XTAL_CLK_HZ / Divider);                     /* Calculate the PLL reference clock */

      Divider = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 24u);

      MCGOUTClock *= Divider;                       /* Calculate the MCG output clock */

    } /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u)) */

  } else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x40u) {

    /* Internal reference clock is selected */

    if ((MCG->C2 & MCG_C2_IRCS_MASK) == 0x0u) {

      MCGOUTClock = CPU_INT_SLOW_CLK_HZ;                                       /* Slow internal reference clock selected */

    } else { /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x0u)) */

      MCGOUTClock = CPU_INT_FAST_CLK_HZ / (1 << ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT));  /* Fast internal reference clock selected */

    } /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x0u)) */

  } else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80u) {

    /* External reference clock is selected */

    MCGOUTClock = CPU_XTAL_CLK_HZ;                                           /* System oscillator drives MCG clock */

  } else { /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80u)) */

    /* Reserved value */

    return;

  } /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80u)) */

  SystemCoreClock = (MCGOUTClock / (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT)));

}
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

Awatar użytkownika
Nefarious19
Newb
Newb
Posty: 80
Rejestracja: sobota 02 sty 2016, 20:45

Re: [FRDM-KL25Z] Ustawienie zegara na 48MHz

Postautor: Nefarious19 » poniedziałek 21 lis 2016, 22:13

Dzięki. Użyłem właśnie Systicka i z użyciem funkcji SystemCoreClockUpdate(); dioda zmienia stan co sekunde równo a bez niej zmoją konfiguracją wolniej więc coś mam pokopane. Dzięki za info.
Plany na przyszłość: C, C++, C#

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1168
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: [FRDM-KL25Z] Ustawienie zegara na 48MHz

Postautor: Antystatyczny » poniedziałek 21 lis 2016, 22:22

Akurat w Kinetisach nie grzebałem przy rejestrach zegarów, więc trudno mi na szybko powiedzieć, gdzie masz błąd. Te podstawową sprawę zawsze miałem wygenerowaną, by nie tracić czasu na grzebanie przy tym. Co innego rejestry peryferiów... Tam grzebałem ostro, bo nie podobały mi się Code Warrior i Kinetis Design Studio.
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.


Wróć do „Freescale - problemy układowe”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 2 gości