garfield

【原创】飞思卡尔kinetis处理器时钟系统及其配置

0
阅读(5766)

本文展示如何配置时钟系统和多功能时钟发生器(MCG)模块在各种可能需要的模式的典型应用。例子将展示进入低功耗运作模式(VKPR)后如何使PLL 的高速芯片运作和如何使用PLL 向前或向后移动在一个低功率/低速度模式。此外,例子提供如何配置频率锁相环(FLL)作为主要的系统时钟源,使用时钟振荡器作为参考时钟。

时钟系统内部结构及其联接图

image

MCG 提供系统级时钟。 MCG 包括:
• 二个单独地trimable内部参考时钟(IRC),一个频率为32 kHz 慢速IRC和一个频率为4 MHz的快速的IRC (固定除2)。
• 频率锁相环(FLL)使用慢速IRC 或一个外部源作为参考时钟。
• 锁相环(FLL)使用外部源作为参考时钟。
•自动修剪器(ATM)允许所有的IRC 被自定义修剪。使之产生的参考时钟频率。
由MCG 提供的时钟归纳如下:
• MCGOUTCLK——这是主系统时钟用来生成核心,总线,和内存时钟。它可以产生一个片上基准振荡器,该片上石英晶体谐振器振荡器,在外部产生方波时钟,FLL 或PLL。

• MCGFLLCLK——在FLL 使能时侯,它作为FLL 的输出。
• MCGPLLCLK ——在PLL 使能时侯,它作为PLL 的输出。
• MCGIRCLK—— 作为选定的IRC 的输出时。选定的IRC 将启用,这个时钟被选择。
• MCGFFCLK ——这是慢速IRC 或FLL 外部参考分频器(FRDIV)分出的外部时钟源。选择慢速IRC 时,这个时钟是在所有模式中除去FLL 旁路内部(FBI)和绕过低功耗内部(BLPI)。该时钟源是由内部参考选择位(IREFS)选定。
除了提供的时钟MCG,还有其他三个系统时钟源可用于各种外围模块:
• OSCERCLK——这个时钟由系统提供振荡器和输出振荡器或外部方波的时钟源。
• ERCLK32K——如果是设置为32 千赫频率在低功率模式这里由RTC 振荡器或系统振荡器输出。
• LPO ——这是低功耗振荡器的输出。这是一个片上,在所有运行中的低功耗模式中,低功耗振荡器输出大约1kHZ 频率。
配置实例
MCG 可配置在几种模式之一提供了广泛的应用的时钟系统和灵活的手段。一些更常用的模式是描述在下面的配置实例。
退出复位,或从一个非常低的漏磁状态中恢复后,MCG 将在20.97 MHz 频率下 FLL 从内部(FEI)与MCGCLKOUT 的模式,假设一个部件调整缓慢IRC 频率至32.768 kHz 的。如果需要不同的MCG 的模式,在软件控制下MCG 可以转移到该模式。
虽然不包括在示例代码,当在MCG 检查状态位时,你应该包括一个“超时”机制。修改时钟选择位后,使能振荡器或PLL,在继续之前,相应的状态位应核实。如果由于某种原因检查到不更新,“while 循环”将永不退出除非超时机制的使用。一个超时计数器应该开始在检查状态位之前。此计数器必须在循环退出后停止和复位。如果超时产生,更新失败,才能根据不同的状态位决定做什么。
例如,如果振荡器不启动,由于PCD 板受损,可以决定继续采用内部专用时钟模式,做一个适当的指示给用户或一个中央监控站。
过渡到PLL 从事外部模式
PLL 在外部模式下使用外部时钟,无论晶体振荡器或外部产生的方波,都作为片上PLL 的参考。一个片上分频器允许提供外部时钟,参考PLL 时钟范围为2–4 MHz。 PLL 提供最精确的时钟源源,过大的频率可以由外部源产生。在这个例子中,一个8 MHz 的晶体是用来生成一个96 MHz 的系统时钟。系统时钟分频器设置这个时钟源使系统性能最大化。 PLL 频率可分为USB 时钟提供48 MHz。 MCG 的配置应尽量减少PLL 抖动(PLL 频率最高与最低的倍增因子)。
代码示例和说明
// If the internal load capacitors are being used, they should be selected
// before enabling the oscillator. Application specific. 16pF and 8pF
selected
// in this example
OSC_CR = OSC_CR_SC16P_MASK | OSC_CR_SC8P_MASK;

// Enabling the oscillator for 8 MHz crystal
// RANGE=1, should be set to match the frequency of the crystal being
used
// HGO=1, high gain is selected, provides better noise immunity but does
draw
// higher current
// EREFS=1, enable the external oscillator
// LP=0, low power mode not selected (not actually part of osc setup)
// IRCS=0, slow internal ref clock selected (not actually part of osc
setup)
MCG_C2 = MCG_C2_RANGE(1) | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK;
// Select ext oscillator, reference divider and clear IREFS to start ext
osc
// CLKS=2, select the external clock source
// FRDIV=3, set the FLL ref divider to keep the ref clock in range
// (even if FLL is not being used) 8 MHz / 256 = 31.25 kHz
// IREFS=0, select the external clock
// IRCLKEN=0, disable IRCLK (can enable it if desired)
// IREFSTEN=0, disable IRC in stop mode (can keep it enabled in stop if
desired)
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3);
// wait for oscillator to initialize
while (!(MCG_S & MCG_S_OSCINIT_MASK)){}
// wait for Reference clock to switch to external reference
while (MCG_S & MCG_S_IREFST_MASK){}
// Wait for MCGOUT to switch over to the external reference clock
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){}
// Now configure the PLL and move to PBE mode
// set the PRDIV field to generate a 4MHz reference clock (8MHz /2)
MCG_C5 = MCG_C5_PRDIV(1); // PRDIV=1 selects a divide by 2
// set the VDIV field to 0, which is x24, giving 4 x 24 = 96 MHz
// the PLLS bit is set to enable the PLL
// the clock monitor is enabled, CME=1 to cause a reset if crystal fails
// LOLIE can be optionally set to enable the loss of lock interrupt
MCG_C6 = MCG_C6_CME_MASK | MCG_C6_PLLS_MASK;
// wait until the source of the PLLS clock has switched to the PLL
while (!(MCG_S & MCG_S_PLLST_MASK)){}
// wait until the PLL has achieved lock
while (!(MCG_S & MCG_S_LOCK_MASK)){}
// set up the SIM clock dividers BEFORE switching to the PLL to ensure
the
// system clock speeds are in spec.
// core = PLL (96MHz), bus = PLL/2 (48MHz), flexbus = PLL/2 (48MHz), flash
= PLL/4 (24MHz)

SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1)
| SIM_CLKDIV1_OUTDIV3(1) | SIM_CLKDIV1_OUTDIV4(3);
// Transition into PEE by setting CLKS to 0
// previous MCG_C1 settings remain the same, just need to set CLKS to
0
MCG_C1 &= ~MCG_C1_CLKS_MASK;
// Wait for MCGOUT to switch over to the PLL
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3){}
// The USB clock divider in the System Clock Divider Register 2
(SIM_CLKDIV2)
// should be configured to generate the 48 MHz USB clock before
configuring
// the USB module.
SIM_CLKDIV2 |= SIM_CLKDIV2_USBDIV(1); // sets USB divider to /2 assuming
reset
// state of the SIM_CLKDIV2 register


PLL 外部模式过度到低功耗内部模式


为了能够使 MCU 移动到VLPR(或等待)模式,MCG 必须设置成低功耗,MCGCLKOUT <=
2 MHz 的低频模式。这种模式是由MCG 的BLPI 模式设置时,选择快速IRC。这个例子显示,
在进入VLPR 前,如何从PLL 外部模式进入这个时钟模式,然后在VLPR 退出后返回该模式。
在VLPR 模式,系统时钟分频器不能改变。 MCG 的BLPI 模式在MCU 电源模式更改为VLPR
之前,应配置这些分压器。


代码示例和说明


// Moving from PEE to BLPI
// first move from PEE to PBE
MCG_C1 |= MCG_C1_CLKS(2); // select external reference clock as MCG_OUT
// Wait for clock status bits to update indicating clock has switched
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){}
// now move to FBE mode
// make sure the FRDIV is configured to keep the FLL reference within
//spec.
MCG_C1 &= ~MCG_C1_FRDIV_MASK; // clear FRDIV field
MCG_C1 |= MCG_C1_FRDIV(3); // set FLL ref divider to 256
MCG_C6 &= ~MCG_C6_PLLS_MASK; // clear PLLS to select the FLL
while (MCG_S & MCG_S_PLLST_MASK){} // Wait for PLLST status bit to clear
//to
// indicate switch to FLL output
// now move to FBI mode
MCG_C2 |= MCG_C2_IRCS_MASK; // set the IRCS bit to select the fast IRC
// set CLKS to 1 to select the internal reference clock
// keep FRDIV at existing value to keep FLL ref clock in spec.
// set IREFS to 1 to select internal reference clock

MCG_C1 = MCG_C1_CLKS(1) | MCG_C1_FRDIV(3) | MCG_C1_IREFS_MASK;
// wait for internal reference to be selected
while (!(MCG_S & MCG_S_IREFST_MASK)){}
// wait for fast internal reference to be selected
while (!(MCG_S & MCG_S_IRCST_MASK)){}
// wait for clock to switch to IRC
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x1){}
// now move to BLPI
MCG_C2 |= MCG_C2_LP_MASK; // set the LP bit to enter BLPI
// set up the SIM clock dividers BEFORE switching to VLPR to ensure the
// system clock speeds are in spec. MCGCLKOUT = 2 MHz in BLPI mode
// core = 2 MHz, bus = 2 MHz, flexbus = 2 MHz, flash = 1 MHz
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0)
| SIM_CLKDIV1_OUTDIV3(0) | SIM_CLKDIV1_OUTDIV4(1);
现在MCGCLKOUT 是2MHZ,选择的是MCU VLPR 电源模式。关于这一细节,请参考电源
管理控制器。当MCU 过渡恢复正常运作模式的时候,MCG 仍然配置为BLPI 模式。MCG 的
配置在PLL 的外部模式下。软件代码如下:
// Moving from BLPI to PEE
// first move to FBI
MCG_C2 &= ~MCG_C2_LP_MASK; // clear the LP bit to exit BLPI
// move to FBE
// clear IREFS to select the external ref clock
// set CLKS = 2 to select the ext ref clock as clk source
// it is assumed the oscillator parameters in MCG_C2 have not been changed
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(3);
// wait for the oscillator to initialize again
while (!(MCG_S & MCG_S_OSCINIT_MASK)){}
// wait for Reference clock to switch to external reference
while (MCG_S & MCG_S_IREFST_MASK){}
// wait for MCGOUT to switch over to the external reference clock
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2){}
//configure PLL and system clock dividers as FEI to PEE example
MCG_C5 = MCG_C5_PRDIV(1);
MCG_C6 = MCG_C6_PLLS_MASK;
while (!(MCG_S & MCG_S_PLLST_MASK)){}
while (!(MCG_S & MCG_S_LOCK_MASK)){}
// configure the clock dividers back again before switching to the PLL
to ensure the system
// clock speeds are in spec.
// core = PLL (96MHz), bus = PLL/2 (48MHz), flexbus = PLL/2 (48MHz), flash
= PLL/4 (24MHz)
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1)
| SIM_CLKDIV1_OUTDIV3(1) | SIM_CLKDIV1_OUTDIV4(3);

MCG_C1 &= ~MCG_C1_CLKS_MASK;
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3){}
FLL 配置问题与参考时钟振荡器
MCG 可以生成所有的系统时钟,使用FILL 时RTC 振荡器被用作参考时钟。 这样做的好处
是有一个准确的参考时钟可以使用,不需要额外的外部组件,应用程序就可以使用实时时钟。
代码示例和说明
// Using the RTC OSC as Ref Clk
// Configure and enable the RTC OSC
// select the load caps (application dependent) and the oscillator enable
bit
// note that other bits in this register may need to be set depending
on the intended use of
the RTC
RTC_CR |= RTC_CR_SC16P_MASK | RTC_CR_SC8P_MASK | RTC_CR_OSCE_MASK;
time_delay_ms(1000); // wait for the RTC oscillator to initialize
// select the RTC oscillator as the MCG reference clock
SIM_SOPT2 |= SIM_SOPT2_MCGCLKSEL_MASK;
// ensure MCG_C2 is in the reset state, key item is RANGE = 0 to select
the correct FRDIV
factor
MCG_C2 = 0x0;
// Select the Reference Divider and clear IREFS to select the osc
// CLKS=0, select the FLL as the clock source for MCGOUTCLK
// FRDIV=0, set the FLL ref divider to divide by 1
// IREFS=0, select the external clock
// IRCLKEN=0, disable IRCLK (can enable if desired)
// IREFSTEN=0, disable IRC in stop mode (can keep it enabled in stop if
desired)
MCG_C1 = 0x0;
// wait for Reference clock to switch to external reference
while (MCG_S & MCG_S_IREFST_MASK){}
// Wait for clock status bits to update
while (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x0){}
// Can select the FLL operating range/freq by means of the DRS and DMX32
bits
// Must first ensure the system clock dividers are set to keep the core
and
// bus clocks within spec.
// core = FLL (48 MHz), bus = FLL (48 MHz), flexbus = PLL (48 MHz), flash
= PLL/2 (24 MHz)
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(0)
| SIM_CLKDIV1_OUTDIV3(0) | SIM_CLKDIV1_OUTDIV4(1);

// In this example DMX32 is set and DRS is set to 1 = 48 MHz from a 32.768
kHz
// crystal
MCG_C4 |= MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(1);

Baidu
map