|
在使用一种CPU时我们必须首先知道CPU是按多少频率工作的,内部各集成的外设是按多少频率工作的,为此使用一种CPU前先应该搞清内部
的时钟机制。本文试图让读者快速了解AT91SAM7处理器的内部时钟。
一.三个时钟源
AT91SAM7S内部有三种时钟源,分别是:SCLK
、
MAINCK 、
PLLCK
SCLK:慢时钟,一个片内集成RC振荡器,频率约32KHz,器件复位后默认使用此时钟,它是器件唯一恒定时钟
MAINCK:主振荡器时钟,主时钟由连接在XIN和XOUT引脚上的3~20MHz晶振产生,
典型连接18.432MHz的晶振,也只有连接18.432MHz的晶振
后才能使用SAM-BA软件进行下载程序。
PLLCK:PLL时钟,将主时钟倍频后输出的时钟,PLL输出的时钟范围为80~200MHz
时钟发生器的用户接口内置在电源管理控制器(PMC)中,下面是时钟发生器的框图:

二.设备时钟
时钟源出来的时钟信号根据不同的用途,分别配置成不同的频率后提供给处理器和片内外设。
主时钟MCK:处理器和外设都将使用主时钟MCK产生自己合适的时钟,无论如何MCK是很重要的,它由主时钟控制器产生。
处理器时钟PCK
:MCK通过处理器时钟控制器得到PCK。
外设时钟:MCK通过外设时钟控制器得到外设使用的时钟,通过外设时钟控制器可打开或关闭提供给外设的时钟,这在低功耗应用中是很有用的。
USB时钟UDPCK:PLLCK通过USB时钟控制器得到UDPCK。
下面是设备用时钟产生框图:

三.启动代码中对时钟的配置
以下是AT91SAM7X-EK板主振荡器18.432MHz晶振获得48MHz主时钟的启动代码:
void
AT91F_LowLevelInit(void)
{
unsigned char i;
// 1 Wait State
necessary to work at 48MHz
AT91C_BASE_MC->MC_FMR = AT91C_MC_FWS_1FWS;
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Init PMC Step 1. Enable Main
Oscillator 使能主振荡时钟
// Main Oscillator startup time is
board specific:
// Main Oscillator Startup Time worst
case (3MHz) corresponds to 15ms (0x40 for AT91C_CKGR_OSCOUNT
field)
/////////////////////////////////////////////////////////////////////////////////////////////////////
AT91C_BASE_PMC->PMC_MOR = (( AT91C_CKGR_OSCOUNT & (0x40 <<8)
| AT91C_CKGR_MOSCEN ));
// Wait Main Oscillator stabilization
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Init PMC Step 2. 配置PLL输出时钟和USB时钟
18.432 * (72+1)/14 =
96,109MHz
// Set PLL to 96MHz (96,109MHz) and
UDP Clock to 48MHz
// PLL Startup time depends on PLL RC
filter: worst case is choosen
// UDP Clock (48,058MHz) is compliant
with the Universal Serial Bus Specification (+/- 0.25% for
full speed)
/////////////////////////////////////////////////////////////////////////////////////////////////////
AT91C_BASE_PMC->PMC_PLLR = AT91C_CKGR_USBDIV_1 |
AT91C_CKGR_OUT_0 | AT91C_CKGR_PLLCOUNT |
(AT91C_CKGR_MUL & (72 << 16)) | (AT91C_CKGR_DIV & 14);
// Wait for PLL stabilization
while(
!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK) );
// Wait until the master clock is established for the case
we already turn on the PLL
while(
!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Init PMC Step 3. 配置MCK为PLL输出分频2,处理器时钟PCK等于MCK
// Selection of Master Clock MCK
(equal to Processor Clock PCK) equal to PLL/2 = 48MHz
// The PMC_MCKR register must not be
programmed in a single write operation (see. Product Errata
Sheet)
/////////////////////////////////////////////////////////////////////////////////////////////////////
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
//
分频2
// Wait until the master clock is established
while(
!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;//选PLL为时钟
// Wait until the master clock is established
while(
!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) );
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Disable Watchdog (write once
register)
/////////////////////////////////////////////////////////////////////////////////////////////////////
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Init AIC: assign corresponding
handler for each interrupt source
/////////////////////////////////////////////////////////////////////////////////////////////////////
AT91C_BASE_AIC->AIC_SVR[0] = (int) AT91F_Default_FIQ_handler
;
for (i = 1; i <
31; i++)
{
AT91C_BASE_AIC->AIC_SVR[i] = (int) AT91F_Default_IRQ_handler
;
}
AT91C_BASE_AIC->AIC_SPU
= (unsigned int) AT91F_Spurious_handler;
}
四.外设时钟控制
在电源管理控制器(PMC)内配置片内外设的时钟是否打开,通过关闭不用的外设时钟达到降低功耗的目的。这时通过电源管理控制器(PMC)
PMC_PCER(外设时钟使能寄存器)
PMC_PCDR(外设时钟禁用寄存器) PMC_PCSR(外设时钟状态寄存器)这三个寄存器来控制的。例如如果要使能
某一外设时钟时将PMC_PCER中对应位置位即可,而禁止这一外设的时钟时将PMC_PCDR内对应位置位即可。器件复位后可控时钟外设的时钟是处于
关闭的 ,为此使用前必须打开,下面是打开PIOA时钟的操作函数:
AT91F_PMC_EnablePeriphClock (
AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ;
AT91F_PMC_EnablePeriphClock是lib_AT91SAM7XXX.h中定义的,AT91C_BASE_PMC器件电源管理器(PMC)地址,AT91C_ID_PIOA
为PIOA在器件中的
外设编号,这个编号在AT91SAM7XXXX.H中被定义。
芯艺设计室(http://www.chipart.cn) 2008.11.10 转载请注明出处!
|