学习北京蓝海微芯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
文章评论(0条评论)
登录后参与讨论