各时钟配置

1.内核时钟设置

 各部分分析:

①、内核时钟源来自于PLL1,假如此时PLL1为996MHz。

②、通过寄存器CCM_CACRR的ARM_PODF位对PLL1进行分频,可选择1/2/4/8分频,假如我们选择2分频,那么经过分频以后的时钟频率是996/2=498MHz。

③、大家不要被此处的2分频给骗了,此处没有进行2分频。

④、经过第②步2分频以后的498MHz就是ARM的内核时钟,也就是I.MX6U的主频。

所以这里我们只需要配置两个寄存器就可以。

  • CCM_CACRR 的 ARM_PODF 位设置分频
  • 寄存器 CCM_ANALOG_PLL_ARMn 设置 PLL1 频率

CCM_CACRR 寄存器以及 ARM_PODF 位与分频的对应关系如下: 

ARM_PODF 位,可以设置为 0~7,分别对应 1~8 分频,要设置 2分频就是给 001就行。

2.1.2 CCM_ANALOG_PLL_ARMn 寄存器

 

ENABLE: 时钟输出使能位,此位设置为1使能PLL1输出,如果设置为0的话就关闭PLL1输出。

DIV_SELECT: 此位设置PLL1的输出频率,可设置范围为:54~108,PLL1 CLK = Fin * div_seclec/2.0,Fin=24MHz。如果PLL1要输出1056MHz的话,div_select就要设置为88。

在修改PLL1时钟频率的时候我们需要先将内核时钟源改为其他的时钟源,PLL1可选择的时钟源如图:

修改I.MX6U主频的步骤就很清晰了,修改步骤如下:

①、 设置寄存器CCSR的STEP_SEL位,设置step_clk的时钟源为24M的晶振。

②、设置寄存器CCSR的PLL1_SW_CLK_SEL位,设置pll1_sw_clk的时钟源为step_clk=24MHz,通过这一步我们就将I.MX6U的主频先设置为24MHz,直接来自于外部的24M晶振。

③、设置寄存器CCM_ANALOG_PLL_ARMn,将pll1_main_clk(PLL1)设置为1056MHz。

④、设置寄存器CCSR的PLL1_SW_CLK_SEL位,重新将pll1_sw_clk的时钟源切换回pll1_main_clk,切换回来以后的pll1_sw_clk就等于1056MHz。

⑤、最后设置寄存器CCM_CACRR的ARM_PODF为2分频,I.MX6U的内核主频就为1056/2=528MHz。

2、PFD时钟设置

设置PLL2和PLL3的各自4路PFD,NXP推荐的这8路PFD频率如表所示:

PFDNXP推荐频率值
PLL2_PFD0358MHz
PLL2_PFD1594MHz
PLL2_PFD2400MHz(实际396MHz)
PLL2_PFD3297MHz
PLL3_PFD0720MHz
PLL3_PFD1540MHz
PLL3_PFD2508.2MHz
PLL3_PFD34454.7MHz

 

 

先设置PLL2的4路PFD频率,用到寄存器是CCM_ANALOG_PFD_528n,寄存器结构如图所示:

 

从图中可以看出,寄存器CCM_ANALOG_PFD_528n其实分为四组,分别对应PFD0~PFD3,每组8个bit,我们就以PFD0为例,看一下如何设置PLL2_PFD0的频率。PFD0对应的寄存器位如下:

PFD0_FRAC: PLL2_PFD0的分频数,PLL2_PFD0的计算公式为528*18/PFD0_FRAC,此为可设置的范围为12~35。如果PLL2_PFD0的频率要设置为352MHz的话PFD0_FRAC=528*18/352=27。

PFD0_STABLE: 此位为只读位,可以通过读取此位判断PLL2_PFD0是否稳定。

PFD0_CLKGATE: PLL2_PFD0输出使能位,为1的时候关闭PLL2_PFD0的输出,为0的时候使能输出。

        如果我们要设置PLL2_PFD0的频率为352MHz的话就需要设置PFD0_FRAC为27,PFD0_CLKGATE为0。PLL2_PFD1~PLL2_PFD3设置类似,频率计算公式都是528*18/PFDX_FRAC(X=1~3),因此PLL2_PFD1=594MHz的话,PFD1_FRAC=16;PLL2_PFD2=400MHz的话PFD2_FRAC不能整除,因此取最近的整数值,即PFD2_FRAC=24,这样PLL2_PFD2实际为396MHz;PLL2_PFD3=297MHz的话,PFD3_FRAC=32。

        接下来设置PLL3_PFD0~PLL3_PFD3这4路PFD的频率,使用到的寄存器是CCM_ANALOG_PFD_480n,此寄存器结构如图所示:

 

从图中可以看出,寄存器CCM_ANALOG_PFD_480n和CCM_ANALOG_PFD_528n的结构是一模一样的,只是一个是PLL2的,一个是PLL3的。寄存器位的含义也是一样的,只是频率计算公式不同,比如PLL3_PFDX=480*18/PFDX_FRAC(X=0~3)。如果PLL3_PFD0=720MHz的话,PFD0_FRAC=12;如果PLL3_PFD1=540MHz的话,PFD1_FRAC=16;如果PLL3_PFD2=508.2MHz的话,PFD2_FRAC=17;如果PLL3_PFD3=454.7MHz的话,PFD3_FRAC=19。

代码:

​
void imx6u_clkinit(void)
{
	unsigned int reg = 0;
	
	
	if((((CCM->CCSR) >> 2) & 0x1 ) == 0) 	/* 当前pll1_sw_clk使用的pll1_main_clk*/
	{	
		CCM->CCSR &= ~(1 << 8);				/* 配置step_clk时钟源为24MH OSC */	
		CCM->CCSR |= (1 << 2);				/* 配置pll1_sw_clk时钟源为step_clk */
	}

	
	CCM_ANALOG->PLL_ARM = (1 << 13) | ((66 << 0) & 0X7F); 	
	CCM->CCSR &= ~(1 << 2);									
	CCM->CACRR = 0;											
	reg = CCM_ANALOG->PFD_528;
	reg &= ~(0X3F3F3F3F);		/* 清除原来的设置 */
	reg |= 32<<24;				/* PLL2_PFD3=528*18/32=297Mhz 	*/
	reg |= 24<<16;				/* PLL2_PFD2=528*18/24=396Mhz(DDR使用的时钟,最大400Mhz) */
	reg |= 16<<8;				/* PLL2_PFD1=528*18/16=594Mhz 	*/
	reg |= 27<<0;				/* PLL2_PFD0=528*18/27=352Mhz  	*/
	CCM_ANALOG->PFD_528=reg;	/* 设置PLL2_PFD0~3 		 		*/

	reg = 0;					/* 清零   */
	reg = CCM_ANALOG->PFD_480;
	reg &= ~(0X3F3F3F3F);		/* 清除原来的设置 							*/
	reg |= 19<<24;				/* PLL3_PFD3=480*18/19=454.74Mhz 	*/
	reg |= 17<<16;				/* PLL3_PFD2=480*18/17=508.24Mhz 	*/
	reg |= 16<<8;				/* PLL3_PFD1=480*18/16=540Mhz		*/
	reg |= 12<<0;				/* PLL3_PFD0=480*18/12=720Mhz	 	*/
	CCM_ANALOG->PFD_480=reg;	/* 设置PLL3_PFD0~3 					*/	

​}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值