PCC - aman396271/Flagchip_Study GitHub Wiki
不是所有外设时钟都可以分频
系统时钟分配
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;
时钟源的que'di确定取决于PCC[MUX]的设定,即PCC_ClkGateSrcType中的内容