最近将以前写的和学的东西整理总结了下,会陆续加载到自己博客中,学有疏,常有漏,只有不断地总结和归纳,才能有进一步的飞跃。
1. 时钟原理
时钟是用于同步工作,SOC内部有很多器件,如CPU、UART、DRAM控制器,GPIO等内部外设,这些东西要彼此协调工作,需要一个同步的时钟系统来指挥。SOC内部有很多部件都需要时钟,而且各自需要的时钟频率不同,没法统一供应,因此设计思路是PLL后先得到一个最高的频率(1GHZ、1.2GHZ),然后各个外设都有自己的分频器再分频得到自己想要的频率。
APLL: MSYS域
MPLL&EPLL:DSYS PSYS
VPLL:Video视频相关模块
2. 时钟构成图
该时钟图可以看出将APLL MPLL EPLL 经过分频器供外围设备使用,
3. 时钟配置
(1)MSYS域(Main System)主时钟:
ARMCLK:给cpu内核工作的时钟,也就是所谓的主频
HCLK_MSYS:MSYS域的高频时钟,给DMC0和DMC1使用(配内存的时候用)
PCLK_MSYS:MSYS域的低频时钟
HCLK_IMEM:给iROM和iRAM(合成iMEM)使用
(2)DSYS域(Display System)显示时钟:
HCLK_DSYS:DSYS域的高频时钟
PCLK_DSYS:DSYS域的低频时钟
(3)PSYS域(Peripheral System)外围时钟:
HCLK_PSYS:PSYS域的高频时钟
PCLK_PSYS:PSYS域的低频时钟
(4)各时钟的典型值:
freq(ARMCLK) = 1000 MHz
freq(HCLK_MSYS) = 200 MHz
freq(HCLK_IMEM) = 100 MHz
freq(PCLK_MSYS) = 100 MHz
freq(HCLK_DSYS) = 166MHz
freq(PCLK_DSYS) = 83MHz
freq(HCLK_PSYS) = 133MHz
freq(PCLK_PSYS) = 66MHz
freq(SCLK_ONENAND) = 133MHz, 166 MHz
4. 时钟计算
FOUT = MDIV * FIN / (PDIV × 2SDV-1)
(1) APLL时钟控制寄存器
(2) 时钟源控制寄存器
(3)时钟分频器控制寄存器
5. 部分代码分析
代码如下:
void clock_init(void)
{
/* 设置时钟为:
* ARMCLK=1000MHz, HCLKM=200MHz, HCLKD=166.75MHz
* HCLKP =133.44MHz, PCLKM=100MHz, PCLKD=83.375MHz,
* PCLKP =66.7MHz
*/
/* SDIV[2:0] : S = 1
* PDIV[13:8] : P = 0x3
* MDIV[25:16]: M = 0x7d
* LOCKED [29]: 1 = 使能锁
* ENABLE [31]: 1 = 使能APLL控制器
* 得出FoutAPLL = 1000MHz FOUT = MDIV X FIN / (PDIV × 2SDIV-1)
*/
APLL_CON = (1<<31)|(1<<29)|(0x7d<<16)|(0x3<<8)|(1<<0);
/* 时钟源的设置
* APLL_SEL[0] :1 = FOUTAPLL
* MPLL_SEL[4] :1 = FOUTMPLL
* EPLL_SEL[8] :1 = FOUTEPLL
* VPLL_SEL[12]:1 = FOUTVPLL
* MUX_MSYS_SEL[16]:0 = SCLKAPLL
* MUX_DSYS_SEL[20]:0 = SCLKMPLL
* MUX_PSYS_SEL[24]:0 = SCLKMPLL
* ONENAND_SEL [28]:1 = HCLK_DSYS
*/
CLK_SRC0 = (1<<28)|(1<<12)|(1<<8)|(1<<4)|(1<<0);
/* 设置分频系数
* APLL_RATIO[2:0]: APLL_RATIO = 0x0
* A2M_RATIO [6:4]: A2M_RATIO = 0x4
* HCLK_MSYS_RATIO[10:8]: HCLK_MSYS_RATIO = 0x4
* PCLK_MSYS_RATIO[14:12]:PCLK_MSYS_RATIO = 0x1
* HCLK_DSYS_RATIO[19:16]:HCLK_DSYS_RATIO = 0x3
* PCLK_DSYS_RATIO[22:20]:PCLK_DSYS_RATIO = 0x1
* HCLK_PSYS_RATIO[27:24]:HCLK_PSYS_RATIO = 0x4
* PCLK_PSYS_RATIO[30:28]:PCLK_PSYS_RATIO = 0x1
*/
CLK_DIV0 = (0x1<<28)|(0x4<<24)|(0x1<<20)|(0x3<<16)|(0x1<<12)|(0x4<<8)|(0x4<<4);
/* SDIV[2:0] : S = 1
* PDIV[13:8] : P = 0xc
* MDIV[25:16]: M = 0x29b
* VSEL [27]: 0
* LOCKED [29]: 1 = 使能锁
* ENABLE [31]: 1 = 使能MPLL控制器
* 得出FOUTmpll = 667MHz
*/
APLL_CON = (1<<31)|(1<<29)|(0x29d<<16)|(0xc<<8)|(1<<0);
}
总结
记得以前在配置时钟时,自认为有一点基础了,就直接跑去看寄存器,进行相应的配置。说实话,里面的寄存器太多了,不知道从哪一个开始先撸,后来做了多次试验后,发现芯片手册每个模块前面都有个大致的电路逻辑图,从图中可以看出一些配置和寄存器处理流程,这个方法在多次寻找需要的寄存器时很是受用。