《ARM裸机》7--时钟系统(基于i.MX6ULL)

     

目录

一、7路PLL时钟源 

二、时钟树

三、内核时钟设置

四、设置PLL和PDF

五、AHB、 IPG 和 PERCLK 根时钟设置

实验编写ccm.c:

 查看100ask_imx6ull_pro_2022.08\04_开发板原理图,可以找到两个时钟源:

                (1)24Mhz CPU 主时钟(Y1) 

                (2)32.768Khz CPU RTC 时钟(Y2)

        i.MX6ULL的始终系统,通过24Mhz的CPU的主始终,然后用PLL倍频,让后用分频器分频,这样就获得了外设所需要的时钟频率。

        一、7路PLL时钟源 

        I.MX6U 的外设有很多,不同的外设时钟源不同, NXP 将这些外设的时钟源进行了分组,
一共有 7 组,这 7 组时钟源都是从 24MHz 晶振 PLL 而来的,因此也叫做 7 组 PLL,这 7 组 PLL
结构如图 所示:

        

         ①、 ARM_PLL(PLL1),此路 PLL 是供 ARM 内核使用的, ARM 内核时钟就是由此 PLL
生成的,此 PLL 通过编程的方式最高可倍频到 1.3GHz。
        ②、 528_PLL(PLL2),此路 PLL 也叫做 System_PLL,此路 PLL 是固定的 22 倍频,不可编程修改。因此,此路 PLL 时钟=24MHz * 22 = 528MHz,这也是为什么此 PLL 叫做 528_PLL 的
原因。此 PLL 分出了 4 路 PFD,分别为: PLL2_PFD0~PLL2_PFD3,这 4 路 PFD 和 528_PLL
共同作为其它很多外设的根时钟源。通常 528_PLL 和这 4 路 PFD 是 I.MX6U 内部系统总线的
时钟源,比如内处理逻辑单元、 DDR 接口、 NAND/NOR 接口等等。
        ③、 USB1_PLL(PLL3),此路 PLL 主要用于 USBPHY,此 PLL 也有四路 PFD,为:
PLL3_PFD0~PLL3_PFD3, USB1_PLL 是固定的 20 倍频,因此 USB1_PLL=24MHz *20=480MHz。
USB1_PLL虽然主要用于USB1PHY,但是其和四路PFD同样也可以作为其他外设的根时钟源。
        ④、 USB2_PLL(PLL7,没有写错!就是 PLL7,虽然序号标为 4,但是实际是 PLL7),看名
字就知道此路PLL是给USB2PHY 使用的。同样的,此路PLL固定为20倍频,因此也是480MHz。
        ⑤、 ENET_PLL(PLL6),此路 PLL 固定为 20+5/6 倍频,因此 ENET_PLL=24MHz * (20+5/6)
= 500MHz。此路 PLL 用于生成网络所需的时钟,可以在此 PLL 的基础上生成 25/50/100/125MHz
的网络时钟。
        ⑥、 VIDEO_PLL(PLL5),此路 PLL 用于显示相关的外设,比如 LCD,此路 PLL 的倍频可以
调整, PLL 的输出范围在 650MHz~1300MHz。此路 PLL 在最终输出的时候还可以进行分频,
可选 1/2/4/8/16 分频。
        ⑦、 AUDIO_PLL(PLL4),此路 PLL 用于音频相关的外设,此路 PLL 的倍频可以调整, PLL
的输出范围同样也是 650MHz~1300MHz,此路 PLL 在最终输出的时候也可以进行分频,可选
1/2/4 分频。

二、时钟树

        

        左边是CLOCK_SWITCHER,,就是7路PLL和8路PFD。

        中间是CLOCK ROOT GENERATOR ,时钟产生器。

        右边是SYSTEM CLOCKS,芯片外设。

        以ESAI 这个外设为例:

        (1 )用CSCMR2[ESAI_CLK_SEL]选择PLL。

        (2)用CS1CDR[ESAI_CLK_PRED]选择前分频。

        (3)用CS1CDR[ESAI_CLK_PODF]选择分频。

三、内核时钟设置

         查看6ULL的数据手册,可以看到ARM内核的时钟频率是通过PLL1经过分频得到的,

分频使用CACRR[ARM_PODF]寄存器。

        比如PLL1的频率是996Mhz,设置CACRR[ARM_PODF]为2分屏,则ARM_CKL_ROOT的频率就是498Mhz,也就是 I.MX6U 的主频。

        要获得其他频率,不仅要设置PLL1的分频率,还要设置PLL1的倍频。

        查看数据手册可知,PLL1的倍频设置需要使用CCM_ANALOG_PLL_ARM[DIV_SELECT]

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

         修改PLL1的频率的步骤:

        (1)将pll1_sw_clk选择其他的频率路线。

                设置CCSR[step_sel]选择24Mhz的OSC。

                设置CCSR[pll1_sw_clk_sek]选择step_clk。

                此时pll1_sw_clk的频率是24Mhz。

        (2)修改PLL1的倍频

                设置CCM_ANALOG_PLL_ARM[DIV_SELECT]修改PLL1。

          (3) 将pll1_sw_clk选择回pll1_main_clk。     

        经过以上步骤PLL1就设置成了了想要的频率,再设置分频,就得到了想要的内核频率。

四、设置PLL和PDF

        设置好主频以后我们还需要设置好其他的 PLL 和 PFD 时钟,PLL1已经设置好了,PLL2(528Mhz)、PLL3(480Mhz)和PLL7(480Mhz)是固定的。PLL4~PLL6 都是针对特殊外设
的,用到的时候再设置。因此,接下来重点就是设置 PLL2 和 PLL3 的各自 4 路 PFD, NXP 推
荐的这 8 路 PFD 频率如表所示:

 查看数据手册:

         PLL2的PFD由CCM_ANALOG_PFD_528n控制。

         PLL3的PFD由CCM_ANALOG_PFD_480n控制。

        CCM_ANALOG_PFD_528n如下:

         CCM_ANALOG_PFD_480n和其一样。

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 的
时候使能输出。

五、AHB、 IPG 和 PERCLK 根时钟设置

        

         7 路 PLL 和 8 路 PFD 设置完成以后最后还需要设置 AHB_CLK_ROOT 和 IPG_CLK_ROOT
总线的时钟, I.MX6U 外设根时钟可设置范围如图所示:

 

         设置AHB_CLK_ROOT,IPG_CLK_ROOT步骤:

                (1)设置CBCMR[pre_periph_clk_sel]选择PLL或者PFD。

                (2)设置CBCDR[periph_clk_sel]位0。

                (3)设置CBCDR[ahb_PODF],设置分频。

                   (4) 设置CBCDR[ipg_podf],设置分频。

        设置PERCLK_CLK_ROOT

         (1)设置CSCMR1[PERCLK_CLK_SEL]来选择24Mhz还是IPG_CLK_ROOT。

         (2)设置CSCMR1[PERCLK_PODF]来设置分频。

实验编写ccm.c:

#include "ccm.h"
void CCM_ARM_SET(int num1,int num2)
{
	/*设置PLL1频率*/	
	CCM->CCSR 		&= ~(1<<8);
	CCM->CCSR 		|= (1<<2);
	CCM_ANALOG->PLL_ARM	&=~(0x111f);
	CCM_ANALOG->PLL_ARM	|=(1<<13);
	CCM_ANALOG->PLL_ARM	|=num1;
	CCM->CCSR		&=~(1<<2);
	/*设置PLL1分频*/	
	CCM->CACRR		&=~(0x111);
	CCM->CACRR		|=num2;
	
}
void CCM_PFD_SET(void)
{
	/*设置PLL2_PFD*/
	
	CCM_ANALOG->PFD_528	&=~(0x3F3F3F3F);
	CCM_ANALOG->PFD_528	|=27<<0;
	CCM_ANALOG->PFD_528	|=16<<8;
	CCM_ANALOG->PFD_528	|=24<<16;
	CCM_ANALOG->PFD_528	|=32<<24;

	/*设置PLL2_PFD*/
	CCM_ANALOG->PFD_480	&=~(0x3F3F3F3F);
	CCM_ANALOG->PFD_480	|=12<<0;
	CCM_ANALOG->PFD_480	|=16<<8;
	CCM_ANALOG->PFD_480	|=17<<16;
	CCM_ANALOG->PFD_480	|=19<<24;
}
void AHB_IPG_PERCLK_SET(void)
{
	CCM->CBCMR 		&= ~(3 << 18);
	CCM->CBCMR 		|= (1 << 18); 
	CCM->CBCDR 		&= ~(1 << 25);
	while(CCM->CDHIPR & (1 << 5));
	
	CCM->CBCDR &= ~(3 << 8); 
	CCM->CBCDR |= 1 << 8; 
	
	CCM->CSCMR1 &= ~(1 << 6);
	CCM->CSCMR1 &= ~(7 << 0);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值