PCC - aman396271/Flagchip_Study GitHub Wiki

不是所有外设时钟都可以分频

系统时钟分配

image 1.SIRC(Slow IRC,慢速内部振荡器)

SCG_SircType tSircStruct =
	{
		.bLock = false,
		.bCm = false,
		.bTrEn = false,
		.bLpen = false,
		.bSten = false,
		.eDivH = SCG_ASYNCCLOCKDIV_BY1,
		.eDivM = SCG_ASYNCCLOCKDIV_BY4,
		.eDivL = SCG_ASYNCCLOCKDIV_BY4,
		.u8TrimSrc = (uint8_t)SCG_IRC_TRIMSRC_RESERVE0
	};
    eRetVal = SCG_SetSIRC(&tSircStruct);

    /* Enable SIRC32K  */
    SCG_Sirc32kType tSirc32kCfg =
    {
    	.bLock = false
    };
    eRetVal = SCG_EnableSIRC32K(&tSirc32kCfg);

2.SOSC(Secondary OSC,外部晶振输入),外部晶振通常为24MHz FOSC:Frequency Oscillator(频率振荡器)

SCG_FoscType tFoscStruct =
	{
		.bLock = false,
		.bCm = true,
		.bCmre = false,
		.bSten = false,
		.bBypass = false,
		.eDivH = SCG_ASYNCCLOCKDIV_BY1,
		.eDivM = SCG_ASYNCCLOCKDIV_BY4,
		.eDivL = SCG_ASYNCCLOCKDIV_BY8,
		.u8Eocv = 0x4
	};
	eRetVal = SCG_EnableFOSC(&tFoscStruct);

3.PLL将FOSC放大为高频主时钟,外部晶振24MHz,需要150MHz,PLL硬件分频为2,则24/4*50/2=150

	SCG_Pll0Type tPll0Cfg =
	{
		.bCm = true,
		.bCmre =false,
		.bLock = false,
		.bSten = true,
	    .eSrc = SCG_PLL0SOURCE_FOSC,

#if SCG_POSTDIV_SUPPORT  /* FC41501MS PLL0 is different */
		/* output clock is 24/8*100/2=150Mhz */
	    .ePrediv = SCG_PLL0PREDIV_BY8,
		.eMult =  84U,
		.ePstDiv = SCG_PLLPSTDIV_BY2,
#else
	    .ePrediv = SCG_PLL0PREDIV_BY4,
	    .eMult =  SCG_PLL0MULTIPLY_BY50,
#endif
	    .eDivH = SCG_ASYNCCLOCKDIV_BY1,
	    .eDivM = SCG_ASYNCCLOCKDIV_BY2,
		.eDivL = SCG_ASYNCCLOCKDIV_BY4
	};
	eRetVal = SCG_EnablePLL0(&tPll0Cfg);

4.系统主时钟分配

	/* Set system clock  */
	SCG_ClockCtrlType tClockCtrlCfg =
	{
	    .bSysClkMonitor = true,
		.eSrc = SCG_CLOCK_SRC_PLL0,
		.eDivCore = SCG_CLOCK_DIV_BY1,
		.eDivBus = SCG_CLOCK_DIV_BY2,
		.eDivSlow = SCG_CLOCK_DIV_BY4,
	};
	eRetVal = SCG_SetClkCtrl(&tClockCtrlCfg);

5.FIRC(Fast IRC,内部高速时钟)

	/* Enable FIRC clock, DIVH=DIV1(96M), DIVM=DIV2(48M), DIVL=DIV4(24M) */
    SCG_FircType tFircCfg =
    {
        .bLock = false,
        .bCm = false,
        .bTrEn = false,
        .bSten = false,
        .eDivH = SCG_ASYNCCLOCKDIV_BY1,
        .eDivM = SCG_ASYNCCLOCKDIV_BY2,
        .eDivL = SCG_ASYNCCLOCKDIV_BY4,
        .u8TrimSrc = (uint8_t)SCG_IRC_TRIMSRC_RESERVE0
    };
    eRetVal = SCG_EnableFIRC(&tFircCfg);

5.NVM时钟源配置(通常使用FIRC)

eRetVal = SCG_SetNvmClk(SCG_NVMCLK_SRC_FIRC);

根据以上时钟分配

FOSC (外部晶振):24 MHz(板载晶振频率)

PLL0:以FOSC为输入,经过预分频、倍频和后分频,产生150 MHz主时钟(示例中24/4*50/2=150MHz)

系统时钟分频:

Core Clock = PLL0 / 1 = 150 MHz

Bus Clock = PLL0 / 2 = 75 MHz

Slow Clock = PLL0 / 4 = 37.5 MHz

内部IRC时钟:

SIRC(慢IRC):12 MHz / 4 = 3 MHz(中间级分频)

FIRC(快IRC):96 MHz / 2 = 48 MHz / 4 = 24 MHz(中间级分频)

NVM(非易失性存储器)时钟源:配置为FIRC(24 MHz)

外设时钟分配

SDK所提供的PCC时钟初始化代码


void Bsp_PCC_Init(void)
{
    uint8_t i;

    static PCC_CtrlType BSP_PCC_Config[] =
    {
        {PCC_CLK_PORTA, true, PCC_CLKGATE_SRC_OFF, PCC_CLK_DIV_BY1},
        {PCC_CLK_PORTB, true, PCC_CLKGATE_SRC_OFF, PCC_CLK_DIV_BY1},
        {PCC_CLK_PORTC, true, PCC_CLKGATE_SRC_OFF, PCC_CLK_DIV_BY1},
        {PCC_CLK_PORTD, true, PCC_CLKGATE_SRC_OFF, PCC_CLK_DIV_BY1},
        {PCC_CLK_PORTE, true, PCC_CLKGATE_SRC_OFF, PCC_CLK_DIV_BY1},
        {EXAMPLE_FTU_PCC, true, PCC_CLKGATE_SRC_OFF, PCC_CLK_DIV_BY1},
        {EXAMPLE_DEBUG_UART_PCC, true, PCC_CLKGATE_SRC_FOSCDIV, PCC_CLK_DIV_BY1},
    };

    for (i = 0U; i < sizeof(BSP_PCC_Config) / sizeof(PCC_CtrlType); i++)
    {
        PCC_SetPcc(&BSP_PCC_Config[i]);
    }
}

有关于外设具体时钟源的设定

typedef enum
{
    PCC_CLKGATE_SRC_OFF        = 0U,  /**< clock source off  */
    PCC_CLKGATE_SRC_FOSCDIV    = 1U,  /**< clock source FOSCDIV  */
    PCC_CLKGATE_SRC_SIRCDIV    = 2U,  /**< clock source SIRCDIV  */
    PCC_CLKGATE_SRC_FIRCDIV    = 3U,  /**< clock source FIRCDIV  */
    PCC_CLKGATE_SRC_RESERVE0   = 4U,  /**< clock source reserve0  */
    PCC_CLKGATE_SRC_RESERVE1   = 5U,  /**< clock source reserve1  */
    PCC_CLKGATE_SRC_PLL0DIV    = 6U,  /**< clock source PLL0DIV  */
    PCC_CLKGATE_SRC_RESERVE2   = 7U   /**< clock source reserve2  */
} PCC_ClkGateSrcType;

image 时钟源的que'di确定取决于PCC[MUX]的设定,即PCC_ClkGateSrcType中的内容