IMX6ULL裸机开发之时钟树分析及配置过程

时钟

时钟树

时钟树由三部分组成:时钟切换控制器,根时钟产生器,系统时钟

一个外设的时钟信号的产生途径:晶振向芯片输入时钟信号,信号进入时钟切换控制器,经过用户配置,产生PLL时钟信号,该信号进入根时钟产生步骤,经过分频或倍频,最终成为系统某个外设的时钟信号。

(这个时钟树难度不大,但是分支太多,需要配置的寄存器也多,所以看起来会比较费劲,但是其原理都是大体一致的)

橙色梯形的是选择器,可以选择不同的PLL时钟作为时钟源;矩形就是分频器(2位,3位,6位)。黄色高亮的就是用来配置选择器的各种寄存器

在这里插入图片描述

时钟切换控制器

PLL:接收锁相环输出时钟和锁相环旁路时钟。 简单来说,锁相环就是用来将外部晶振进行倍频,以实现稳定且高频的时钟信号。

由下面的时钟切换图可知,IMX6U总共有7组PLL:

PLL1(996M)、PLL2(528M)、PLL3(480M)、PLL4、PLL5、PLL6、PLL7

其中PLL2、PLL3各自有4组PFD,这些PFD以PLL为基础,经过不同的分频系数可以产生不同频率的时钟,在参考手册的相关寄存器的地方,可以看到官方有推荐的配置参数。(《IMX6UL参考手册》P714~716)

在这里插入图片描述

根时钟产生器

在时钟切换控制器配置完成之后的输出时钟就成了根时钟产生器的时钟源,在根时钟产生器中,经过寄存器配置之后,就成为了外设时钟的时钟源。
在这里插入图片描述
经过以上的叙述,时钟信号从晶振走到外设的大体的过程已经清晰明了。打个比方:时钟信号是一辆车,外设则是终点站,各种选择器则是红绿灯。现在车在马路上要走到终点站,这条路径则是有我们自己设置的,可以有各种不同的路径;当然车速也是有我们自己设置(即分频、倍频)。路径的选择就通过各种选择器来进行配置,这些选择器则就是相关寄存器上的某个段,通过对这些段的配置,我们给汽车规定好了方向,通过分频器,我们给汽车规定好了速度,这样汽车就能走到终点站即外设了。

常见的选择器

选择器的作用是对时钟源进行分频,这里按照时钟树顺序来看。时钟树中提到的总共13个,都以CLX_SEL结尾。(但是还有其他不同外设上使用的,需要看参考手册)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
还有一些其它的选择器这里就不赘述了,直接看数据手册的第18章的 CCM Memory Map/Register Definition 这一小节的介绍即可。

分频器

就是用来进行时钟分频的,也是某些寄存器上的某个段。这里举个例子,不过多陈述
在这里插入图片描述
如图所示,一般这种 divide by x 的就是分频,图片是一个用在ARM根时钟上的分频器,支持0~8分频,这是一个3bit分频器。

NOTE:如果 arm_freq_shift_divider 设置为’1’,那么任何对 arm_podf 的新写操作将一直保持到 Arm_clk_switch_req 信号产生断言。

配置ARM内核时钟

在这里插入图片描述
系统运行的时钟是PLL1,那么当我们要修改这个时钟的时候,不能直接修改。由上图可知,pll1_sw_clk 有2个可选时钟源:pll1_main_clk 和 step_clk。这样一来,我们可以先让 step_clk 作为 pll1_sw_clk 的时钟源(①),当我们修改完pll1时钟后,再让 pll1_main_clk 作为 pll1_sw_clk 的时钟源(②),然后再对时钟进行分频(③)。然后ARM内核时钟就初始化完毕了。这样就可以点灯了。

配置PLL2和3的时钟

时钟树中推荐的PLL2和PLL3及其对应的PFD时钟频率(PDF3应该是297):
在这里插入图片描述
对寄存器CCM_ANALOG_PFD_528n进行配置就是对PLL2时钟及其各路PFD进行配置。Reset这里指的是默认参数,[PFD3_FRAC]段应该为 100000。
在这里插入图片描述
对寄存器CCM_ANALOG_PFD_480n进行配置就是对PLL3时钟及其各路PFD进行配置。Reset这里指的是默认参数。
在这里插入图片描述

初始化代码

void imx6u_clkinit(void)
{
    /* 1、设置 ARM 内核时钟为 528MHz */
    unsigned int reg = 0;				//643页
    if((((CCM->CCSR)>>2) & 0X1) == 0)	//此时时钟源是:pll1_main_clk
    {
        CCM->CCSR &= ~(1 << 8);			//配置step_clk时钟源为osc_clk(24M)
        CCM->CCSR |= (1<< 2);			//切换到时钟源:step_clk
    }
    //配置时钟pll1_main_clk				 //694页
    //bit[6:0]: 88, 由公式:Fout = Fin * div_select / 2.0
    //1056=24*div_select/2.0, 得出:div_select=88
    // (88 << 0) & 0X7F 等同于 88
    CCM_ANALOG->PLL_ARM = (1 << 13) | ((88 << 0) & 0X7F);
    CCM->CCSR &= ~(1 << 2);				//切换回时钟源:pll1_main_clk
    CCM->CACRR = 1;						//配置pll1时钟为2分频

    /***************************到这一步就可以点灯了********************************/
    /***************************以下是PLL时钟源配置********************************/

    /* 2、设置 PLL2(SYS PLL)各个 PFD */
    reg = CCM_ANALOG->PFD_528;
    reg &= ~(0X3F3F3F3F);		//初始化寄存器CCM_ANALOG_PFD_528
    reg |= 32 << 24;			//给PFD3_FRAC段赋值
    reg |= 24 << 16;			//给PFD2_FRAC段赋值
    reg |= 16 << 8;				//给PFD1_FRAC段赋值
    reg |= 27 << 0;				//给PFD0_FRAC段赋值
    CCM_ANALOG->PFD_528 = reg;

    /* 3、设置 PLL3(SYS PLL)各个 PFD */
    reg = 0;
    reg = CCM_ANALOG->PFD_480;	
    reg &= ~(0X3F3F3F3F);		//初始化寄存器CCM_ANALOG_PFD_480
    reg |= 19 << 24;			//给PFD3_FRAC段赋值
    reg |= 17 << 16;			//给PFD2_FRAC段赋值
    reg |= 16 << 8;				//给PFD1_FRAC段赋值
    reg |= 12 << 0;				//给PFD0_FRAC段赋值
    CCM_ANALOG->PFD_480 = reg;

    /***************************以下是其他外设时钟源配置********************************/

    /* IPG_CLK_ROOT	和 PERCLK_CLK_ROOT 要用到 AHB 时钟 */
    /* 4、设置 AHB 时钟 最小 6Mhz, 最大 132Mhz */
    CCM->CBCMR &= ~(3 << 18);	
    CCM->CBCMR |= (1 << 18);		/* pre_periph_clk=PLL2_PFD2=396MHz */
    CCM->CBCDR &= ~(1 << 25);		/* periph_clk=pre_periph_clk=396MHz */
    while(CCM->CDHIPR &(1 << 5));	/* 等待握手完成 */

    #if 0
    CCM->CBCDR &= ~(7 << 10);/* CBCDR 的 AHB_PODF 清零 */
    CCM->CBCDR |= 2 << 10; /* AHB_PODF 3 分频,AHB_CLK_ROOT=132MHz */
    while(CCM->CDHIPR & (1 << 1));/* 等待握手完成 */
    #endif

    /* 5、设置 IPG_CLK_ROOT 最小 3Mhz,最大 66Mhz */
    CCM->CBCDR &= ~(3 << 8);	/* CBCDR 的 AHB_PODF 清零 */
    CCM->CBCDR |= 1 << 8;		/* IPG_PODF 2 分频,IPG_CLK_ROOT=66MHz */

    /* 6、设置 PERCLK_CLK_ROOT 时钟 */
    CCM->CSCMR1 &= ~(1 << 6);		/* PERCLK_CLK_ROOT 时钟源为 IPG */
    CCM->CSCMR1 &= ~(7 << 0);		/* PERCLK_PODF 位清零,即 1 分频 */
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值