Chinaunix首页 | 论坛 | 博客
  • 博客访问: 335950
  • 博文数量: 92
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 960
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-21 19:38
文章分类

全部博文(92)

文章存档

2010年(71)

2009年(21)

我的朋友

分类: 嵌入式

2010-06-15 09:25:01

s3c2440时钟文档

S3C2440 CPU默认的工作主频为12MHz16.9344MHz,这里使用最多的是12M。使用PLL电路可以产生更高的主频供CPU及外围器件使用。

      S3C2440有两个PLLMPLLUPLLUPLL专用与USB设备。MPLL用于CPU及其他外围器件。

      通过MPLL会产生三个部分的时钟频率:FCLKHCLKPLCKFCLK用于CPU核,HCLK用于AHB总线的设备(比如SDRAM)PCLK用于APB总线的设备(比如UART)。从时钟结构图中可以查看到使用不同时钟频率的硬件。

下面介绍MPLL的启动流程:

1、上电几毫秒后,晶振输出稳定,FCLK=晶振频率,nRESET信号恢复高电平后,CPU开始执行指令。

2、我们可以在程序开头启动MPLL,在设置MPLL的几个寄存器后,需要等待一段时间(Lock Time)MPLL的输出才稳定。在这段时间(Lock Time)内,FCLK停振,CPU停止工作。Lock Time的长短由寄存器LOCKTIME设定。

3Lock Time之后,MPLL输出正常,CPU工作在新的FCLK下。

 

设置S3c2440的时钟频率就是设置MPLL的几个寄存器:

1LOCKTIME:设为0x00ffffff

前面说过,MPLL启动后需要等待一段时间(Lock Time),使得其输出稳定。位[23:12]用于UPLL,位[11:0]用于MPLL。使用确省值0x00ffffff即可。

2CLKDIVN:用来设置FCLK:HCLK:PCLK的比例关系,默认为1:1:1

这里值设为0x05,即FCLK:HCLK:PCLK=1:4:8

3MPLLCON:设为(0x7f << 12)|(0x02 << 4)|(0x01),即0x7f0021

对于MPLLCON寄存器,[19:12]MDIV[9:4]PDIV[1:0]SDIV。有如下计算公式:

MPLL(FCLK) = (m * Fin)/(p * 2^s)

其中: m = MDIV + 8, p = PDIV + 2

Fin 即默认输入的时钟频率12MHzMPLLCON设为0x7f0021,可以计算出FCLK=400MHz,再由CLKDIVN的设置可知:HCLK=100MHzPCLK=50MHz

 

到这里我们应该彻底弄清楚了程序中经常出现的几个CLK

Fin,MPLL,UPLL,FCLK,HCLK,PCLK.

FinCPU外围接的晶振本身的频率,通常为12MHz

MPLLUPLL分别指的是用于供整机系统的PLL和专用于USBUPLL

FCLK = MPLL = (m * Fin)/(p + 2^s);

HCLK,PCLKCLKDIVN寄存器的影响,即当FCLK确定后,CLKDIVN决定了HCLKPCLK

 

 

 

ADS中配置时钟:

Main 中输入要设置的内核时钟(FCLK)和分频比(148

int Main(void)

{   

 

    SetSysFclk(FCLK_400M);

ChangeClockDivider(2, 1);

…..

}

2440lib.c文件中定义时钟设置函数:

void SetSysFclk(int val)

{

       rMPLLCON = val;

}

 

 

void ChangeClockDivider(int hdivn,int pdivn)

{

     // hdivn,pdivn FCLK:HCLK:PCLK

     //     0,0         1:1:1

     //     0,1         1:1:2

     //     1,0         1:2:2

     //     1,1         1:2:4

     //     2,0         1:4:4

     //     2,1         1:4:8

     //     3,0         1:3:3

     //     3,1         1:3:6

    rCLKDIVN = (hdivn<<1) | pdivn;   

 

       if (hdivn == 2)

              rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<9);              

       if (hdivn == 3)

              rCAMDIVN = (rCAMDIVN & ~(3<<8)) | (1<<8);

}

其实简化了写就是这样的:

void clock_init(void)

{

        rLOCKTIME = 0xFFFFFF;

 rCLKDIVN  = 0x5;

     rMPLLCON = 0x7f0021;   

}

 

U-boot中设置时钟:

board/TX2440/TX2440.c中的board_init函数

/* S3C2440: Mpll,Upll = (2*m * Fin) / (p * 2^s)

 * m = M (the value for divider M)+ 8, p = P (the value for divider P) + 2

 */

#define S3C2440_MPLL_400MHZ     ((0x7f<<12)|(0x02<<4)|(0x01))

#define S3C2440_UPLL_48MHZ      ((0x38<<12)|(0x02<<4)|(0x02))

#define S3C2440_CLKDIV          0x05    /* FCLK:HCLK:PCLK = 1:4:8 */

int board_init (void)

{

       S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();

       S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

 ………

 

              /* FCLK:HCLK:PCLK = 1:4:8 */

        clk_power->CLKDIVN = S3C2440_CLKDIV;

 

/* 如果HDIVN不为0CPU总线模式从Fast Bus Mode 变为Asynchronous Bus Mode  */

        __asm__(    "mrc    p15, 0, r1, c1, c0, 0\n"    /* read ctrl register   */ 

                    "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */ 

                    "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */ 

                    :::"r1"

                    );

 

        /* to reduce PLL lock time, adjust the LOCKTIME register */

        clk_power->LOCKTIME = 0xFFFFFF;

 

        /* configure MPLL =FCLK=400MHZ*/

        clk_power->MPLLCON = S3C2440_MPLL_400MHZ;

 

        /* some delay between MPLL and UPLL */

        delay (4000);

 

        /* configure UPLL48MHZ FOR USB*/

        clk_power->UPLLCON = S3C2440_UPLL_48MHZ;

 

        /* some delay between MPLL and UPLL */

        delay (8000);

       

       …….

       return 0;

}

 

阅读(1944) | 评论(0) | 转发(0) |
0

上一篇:链表

下一篇:s3c2440串口文档

给主人留下些什么吧!~~