快速掌握ATEML ARM7系列文章(2) AT91SAM7S时钟

 
      在使用一种CPU时我们必须首先知道CPU是按多少频率工作的,内部各集成的外设是按多少频率工作的,为此使用一种CPU前先应该搞清内部

  的时钟机制。本文试图让读者快速了解AT91SAM7处理器的内部时钟。

  一.三个时钟源

  AT91SAM7S内部有三种时钟源,分别是:SCLK MAINCK PLLCK

  SCLK:慢时钟,一个片内集成RC振荡器,频率约32KHz,器件复位后默认使用此时钟,它是器件唯一恒定时钟

  MAINCK:主振荡器时钟,主时钟由连接在XINXOUT引脚上的320MHz晶振产生, 典型连接18.432MHz的晶振,也只有连接18.432MHz的晶振

  后才能使用SAM-BA软件进行下载程序。

  PLLCKPLL时钟,主时钟倍频后输出的时钟,PLL输出的时钟范围为80200MHz

  时钟发生器的用户接口内置在电源管理控制器(PMC)中,下面是时钟发生器的框图:

  二.设备时钟

时钟源出来的时钟信号根据不同的用途,分别配置成不同的频率后提供给处理器和片内外设。

  主时钟MCK处理器和外设都将使用主时钟MCK产生自己合适的时钟,无论如何MCK是很重要的,它由主时钟控制器产生。

  处理器时钟PCK MCK通过处理器时钟控制器得到PCK

  外设时钟:MCK通过外设时钟控制器得到外设使用的时钟,通过外设时钟控制器可打开或关闭提供给外设的时钟,这在低功耗应用中是很有用的。

  USB时钟UDPCKPLLCK通过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  转载请注明出处!

 

芯艺设计室    蒙ICP备06005492号

Copyright© 2004-2011 ChipArt Design House All Rights Reserved