⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock_switching_driver.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 C
字号:
//*----------------------------------------------------------------------------
//*      ATMEL Microcontroller Software Support  -  ROUSSET  -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name           : clock_switching_driver.c
//* Object              : Driver to switch the clock source in the AT91M42800A
//*
//* 1.0 08/01/01 S.C    : Creation
//* Note : The switching times are specified in the software.
//* 1.1 09/07/01 PF		: Add Prescaler setting.
//*----------------------------------------------------------------------------


/*------------------ Files to be included Definition ------------------------*/
#include "parts/m42800/lib_m42800.h"
#include "periph/power_saving/lib_power_save.h"
#include "clock_switching_driver.h"

/*---------------------------- Global Variable ------------------------------*/
char switching_conducted = 0 ; //* Allows to know when the switching is achieved

//*----------------------------------------------------------------------------
//* Function Name       : Prescaler_switching
//* Object              : Prescaler switching
//* Input Parameters    : <pres> Prescaler value (2 to 64)
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void prescaler_switching (int pres)
{

   u_int PMC_cgmr_temp ;

   		if (pres == PMC_PRES_NONE)
        {
			PMC_cgmr_temp = ((at91_clock_generator_state () & 0xFFFFFFF0 ) | PMC_PRES_NONE )  ;
			PMC_BASE->PMC_CGMR = PMC_cgmr_temp ;
		}

        if (pres == PMC_PRES_DIV2)
        {
			PMC_cgmr_temp = ((at91_clock_generator_state () & 0xFFFFFFF0) | PMC_PRES_DIV2 )  ;
			PMC_BASE->PMC_CGMR = PMC_cgmr_temp ;
		}

        if (pres == PMC_PRES_DIV4)
        {
			PMC_cgmr_temp = ((at91_clock_generator_state () & 0xFFFFFFF0) | PMC_PRES_DIV4 )  ;
			PMC_BASE->PMC_CGMR = PMC_cgmr_temp ;
		}


        if (pres == PMC_PRES_DIV8)
        {
			PMC_cgmr_temp = ((at91_clock_generator_state () & 0xFFFFFFF0) | PMC_PRES_DIV8 )  ;
			PMC_BASE->PMC_CGMR = PMC_cgmr_temp ;
		}


        if (pres == PMC_PRES_DIV16)
        {
			PMC_cgmr_temp = ((at91_clock_generator_state () & 0xFFFFFFF0) | PMC_PRES_DIV16 )  ;
			PMC_BASE->PMC_CGMR = PMC_cgmr_temp ;
		}


        if (pres == PMC_PRES_DIV32)
        {
			PMC_cgmr_temp = ((at91_clock_generator_state () & 0xFFFFFFF0) | PMC_PRES_DIV32 )  ;
			PMC_BASE->PMC_CGMR = PMC_cgmr_temp ;
		}

        if (pres == PMC_PRES_DIV64)
        {
			PMC_cgmr_temp = ((at91_clock_generator_state () & 0xFFFFFFF0) | PMC_PRES_DIV64 )  ;
			PMC_BASE->PMC_CGMR = PMC_cgmr_temp ;
		}


}


//*----------------------------------------------------------------------------
//* Function Name       : mck_clock_speed
//* Object              : Driver to choice the clock source and the PLL
//*                       frequency output
//* Input Parameters    :<target_source> clock source
//*                 'source' = 0 : low frequency oscillator output => MCK
//*                 'source' = 1 : main oscillator output => MCK
//*                 'source' = 2 : PLL output =MCK
//*                      <frequency_multiplier> allows to multiply the main
//*                       oscillator frequency ( field B_MUL +1).
//*						: pres = Prescaler NEW.
//* Output Parameters   : None
//*----------------------------------------------------------------------------
void mck_clock_speed (short target_source, u_int frequency_multiplier, u_int prescaler)
{
    u_int pmc_cgmr_status ;
    u_int switch_choice ;
    u_int loop ;

    	switching_conducted = FALSE ;

		frequency_multiplier = frequency_multiplier - 1 ;

		pmc_cgmr_status = at91_clock_generator_state () ;  //* PMC_CGMR reading NEW

        switch_choice = pmc_cgmr_status & CSS_MASK ;

        switch (switch_choice)
        {
            case PMC_CSS_LF:                               //* The actual source clock is the LF osc.

                switch (target_source)
                {
                    case TO_LF_OSCILLATOR : 							//* It's the actual clock source

                        prescaler_switching (prescaler);

                    break ;


                    case TO_PLL_OUTPUT :								//* To the PLL output ((Switching Time = 18 ms
                    													//*						with PLLCOUNT = 3 and
                    													//*						OSCOUNT = 0x2f)
						frequency_multiplier = (frequency_multiplier <<B_MUL) ;
						pmc_cgmr_status &= 0xFFF000FF ;
						pmc_cgmr_status |= frequency_multiplier ;
                        at91_clock_generator_mode ( pmc_cgmr_status ) ;

                        while ((at91_clock_get_pll_status () & PMC_PLL_LOCK) ==0 ) {} ;

                        at91_clock_generator_mode ( pmc_cgmr_status | PMC_CSS_PLL ) ;

                        prescaler_switching (prescaler);

                        break ;
                }
            break ;

            case PMC_CSS_PLL:                              //* The actual source clock is the internal PLL
                switch (target_source)
                {
                    case TO_LF_OSCILLATOR :                               //* To the LF osc.(Switching Time = 14 ms)

                        pmc_cgmr_status &= ~CSS_MASK ;

                        /* Switching to the LF output oscillator */
                        at91_clock_generator_mode ( pmc_cgmr_status ) ;
                        for (loop = 5000; loop > 0; loop--);

                        pmc_cgmr_status &= ~0x7FF00 ;
                        at91_clock_generator_mode ( pmc_cgmr_status ) ;

                        prescaler_switching (prescaler);

                        break ;


                    case TO_PLL_OUTPUT :                               //* It's the actual clock source

                        /* First: PLL start-up */

						frequency_multiplier = (frequency_multiplier <<B_MUL) ;
						pmc_cgmr_status &= 0xFFF000FF ;
						pmc_cgmr_status |= frequency_multiplier ;
						at91_clock_generator_mode ( pmc_cgmr_status ) ;

						while ((at91_clock_get_pll_status () & PMC_PLL_LOCK) ==0 ) {} ;

                        prescaler_switching (prescaler);

                        break ;
                }
        }




}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -