首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

S5PC100 时钟配置详解(2)

S5PC100 时钟配置详解(2)

下面我们以一个实例来配置ARM核的时钟和总线的时钟,配置的具体时钟频率由下图所示。



  S5PC100的时钟系统分为三个域:D0,D1,D2。不同的域给不同的模块提供时钟。在这里我们只关心D0域和D1域。



现在想把ARMCLK配置成667MHZ,HCLK0配置成166MHZ,PCLK0配置成83MHZ,HCKL1配置成133MHZ,PCLK1配置成66MHZ。





第一步:选择路径



XXTI>APLL->DIVAPLL->DIVARM->ARMCLK

XXTI->APLL->DIVAPLL->DIVARM->DIVD0_BUS->HCLK0

XXTI->APLL->DIVAPLL->DIVARM->DIVD0_BUS->DIVPCLK0->PCLK0



关于HCLK1和PCLK1的时钟路径在选择的时候就都有两条:

其中一条是APLL倍频之后,然后由DIVAM分频后提供的。在这里我们不选择这一条路径。为什么呢?在S5PC100的datasheet中明确说明,DIVAM最高能承受的时钟信号是667MHZ,图中也有标明。由于我们给ARMCLK的时钟是667MHZ,在达到之前还需要通过分频器分频,所以APLL倍频后的时钟频率在这里是要大于667MHZ的。



XXTI->MPLL->DIVD1_BUS->HCLK1

XXTI->MPLL->DIVD1_BUS->DIVPCLK->PCLK1



第二步:配置相关的寄存器(倍频器(PLLCON),分频器(DIV),时钟源选择器(MUX))

在这里我说一下ARMCLK,HCLK0,PCLK0的配置方法,大家可以自己按照datasheet配置一下HCLK1,PCLK1。



XXTI>APLL->DIVAPLL->DIVARM->ARMCLK

XXT1的输入时钟是12MHZ,首先要配置APLL。查看datasheet:





(1)PLL需要屏蔽一段时间,以达到输出稳定的倍频时钟。这个和你开车一样,并不是一下就可以提到你想要的车速,需要一段时间的国度,才可以达到你想要的车速。



需要屏蔽的时间从手册上可以知道,如果输入的是12MHZ,需要屏蔽300us,也就是将PLL_MASKTIME设置成0xE10。





(2)设置倍频值



PLL的倍频值由MDIV,PDIV,SDIV这三个倍频因子决定,即给他们不同的值我们得到不同的频率。他们之间有个换算规则,APLL的换算规则如下:





在这里我们将APLL配置成输出1332MHZ的时钟频率,需要将SDIV的值设为0,PDIV的值设为3,MDIV的值设为333。

主意最后还要将APLL使能哦,即将第31位设为1。




为了简化开发,一般会有如下固定值给开发人员来设定:



(3)设置分频值



    ARMCLK需要通过DIVAPLL和DIVARM两个分频器分频后得到,手册上说明这两个分频器必须有一个的分频值要大于1。

从手册找到设置分频器的寄存器,



DIVAPLL的值设为1,DIVARM的值设为0,DIVD0_BUS的值设为3,DIVPCLK0的值设为1 即可得到:

ARMCLK = 1332 / 2 = 666MHZ

HCLK0  = 666 / 4  = 166MHZ

PCLK0  = 166 / 2  = 83MHZ



最后给出配置的实验代码:
system_clock_init:

    ldr r0,=S5PC100_CLOCK_BASE




/*set clock divider*/

    ldr r1,=(1 << 0) + (0 << 4) + (3 << 8) + ( 1 << 12) + ( 1 << 16);

    str r1,[r0,#0x0300]



    ldr r1,=(1 << 12) + (1 << 16);

    str r1,[r0,#0x0304]




/*set lock time*/

    ldr r1,=S5PC100_PLL_MASKTIME

    str r1,[r0,#0x0000]

    str r1,[r0,#0x0004]

    str r1,[r0,#0x0008]

    str r1,[r0,#0x000c]




@APLL_CON ~1334MHZ


@SDIV 0, PDIV 3, MDIV 333   1332MHZ


@ldr r1,=(APLL_MDIV << 16) + (APLL_PDIV << 8) + (APLL_SDIV << 0)

    ldr r1,=(1 << 31) + (333 << 16) + (3 << 8) + ( 0 << 0)

    str r1,[r0,#0x0100]






@MPLL_CON ~600MHZ


@SDIV 1, PDIV 3,MDIV 133   266MHZ


@ldr r1,=(MPLL_MDIV << 16) + (MPLL_PDIV << 8) + (MPLL_SDIV << 0)

    ldr r1,=(1 << 31) + (133 << 16) + (3 << 8) + (1 << 0)

    str r1,[r0,#0x0104]




/*Set Source Clock*/

    ldr r1,=0x11        @APLL_SEL 1,MPLL_SEL 1

    str r1,[r0,#0x0200] @CLK_SRC0




/*wait at least 200us to stablize all clock*/

    ldr r2,=0x10000

1:  subs r2,r2,#1

    bne 1b



    mov pc,lr



stop:


b stop

最后顺便提一下,有些人总是在思考一个问题”我的模块具体属于哪一个时钟域呢”。这个问题手册上是有说明的,可以通过 CLK_GATE寄存器知道,例如S5PC100的PWM模块,它的时钟是由谁提供的呢?










如何知道自己的时钟是否配置正确了,可以通过示波器去检测,也可以通过流水灯实验观察流水灯的速度。这里我们将ARMCLK的时钟设为了667MHZ,此时观看一下流水灯的速度,将ARMCLK时钟域调低一点(怎么调呀,设对应分频器的值就可以了哦),观看流水灯的速度,可以看到明显变慢。
返回列表