原创 S3C2410时钟初始化

2009-9-18 10:23 2478 4 4 分类: MCU/ 嵌入式

  学习北京蓝海微芯2410开发板时,对系统时钟初始化
部分代码的简单分析:


/*************************************************
Function name: SystemClockInit
Parameter    : void
Description  : 系统时钟频率初始化
Return      : void
Argument     :
Autor & date :
**************************************************/
void SystemClockInit(void)
{
 ClkPara.mclk = 192;
 ClkPara.pclk = 4;
 ClkPara.sclk = 1;
 set_pll();
}


程序中有如下定义:
#define EXT_OSC_CLK 12000000 //外部晶振频率


static struct{
 U32 mclk;
 U32 pclk;
 U32 sclk;
 U32 freq;
} ClkPara;  //定义一个时钟频率的数据结构


static U32 clk_div_val;


SystemClockInit函数设置了MDIV=192,PDIV=4,SCLK=1,
然后继续执行set_pll函数。


改函数原型如下:


/*********************************************************************
Function name: set_pll
Parameter    : void
Description  : 设置PLL
Return      : void
Argument     : 主要是设置ClkPara.mclk,ClkPara.pclk,ClkPara.sclk这个变量
频率的计算:m=(ClkPara.mclk+8),p=(ClkPara.pclk+2),s=ClkPara.sclk
           Fin="10" 000000(外部输入频率)
           系统主频=(m*Fin)/(p*(2的s次方))
Autor & date :
*********************************************************************/
static void set_pll(void)
{
 U32 old_freq;
 
 if(ClkPara.mclk>255)
  ClkPara.mclk = 255;
 if(ClkPara.pclk>63)
  ClkPara.pclk = 63;
 if(ClkPara.sclk>3)
  ClkPara.sclk = 3;


 old_freq = ClkPara.freq;
 ClkPara.freq = (EXT_OSC_CLK*(ClkPara.mclk+8))/((ClkPara.pclk+2)<<ClkPara.sclk);
 if((ClkPara.freq>=270000000)||(ClkPara.freq<5*EXT_OSC_CLK)) {
  ClkPara.mclk = 192;
  ClkPara.pclk = 4;
  ClkPara.sclk = 1;
  ClkPara.freq = EXT_OSC_CLK*180U/12U;
 }
 
 clk_div_val = 0;
 if(ClkPara.freq>=80000000) {
  if(ClkPara.freq>=120000000) {
   clk_div_val |= 2;
   if(ClkPara.freq>=160000000)
    clk_div_val |= 1;
  } else
   clk_div_val |= 1;  //80~120MHz
 }
 
 if(old_freq<ClkPara.freq)
  ChangeClockDivider();
 rMPLLCON = (ClkPara.mclk << 12) | (ClkPara.pclk << 4) | ClkPara.sclk;
 ChangeClockDivider();
}


该函数根据公式计算出了主时钟频率为200MHZ,根据MCLK,PCLK,SCLK的值设置了MPLL寄存器。
并设置了异步总线模式。
对于详细的代码解析日后再做补充。


ChangeClockDivide()函数原型如下:
/*******************************************************
Function name: ChangeClockDivider
Parameter    : void
Description  : void
Return      : void
Argument     :
Autor & date :
*******************************************************/
static void ChangeClockDivider(void)
{
     // 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
    rCLKDIVN = clk_div_val ;//(hclk_div<<1) | pclk_div;


    if(clk_div_val&2)
        MMU_SetAsyncBusMode();
    else
        MMU_SetFastBusMode();
}


MMU_SetFastBusMode()函数原型如下:
;void MMU_SetAsyncBusMode(void)
; FCLK:HCLK= 1:2
   EXPORT MMU_SetAsyncBusMode
MMU_SetAsyncBusMode
   mrc p15,0,r0,c1,c0,0
   orr r0,r0,#R1_nF:OR:R1_iA
   mcr p15,0,r0,c1,c0,0
   MOV_PC_LR


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /1 下一条