在配置时钟之前,我们首先要明确以下几点
要点
1、JZ2440上电后内部时钟是怎样配置的?
答:如图1所示,① 单片机上电;② 等Power输出高电平后时钟起振(时钟根据OM[3:2]的值选择,这里的FCLK=晶振频率);②-③ 为复位引脚等待电源稳定,然后才输出高电平(由复位芯片控制);④ 设置PLL,同时锁定Lock Time 时长(此段时间内CPU停止工作);⑤ PLL工作;⑥ FCLK等于PLL输出的新时钟。
|
2、我们所使用的时钟源是来自哪里的以及它的频率是多少?
答:由图2我们知道S3C2440的时钟源是来自于晶体振荡器和外部时钟中的一个,而OM[3:2]的取值决定了S3C2440的时钟源到底是来着于哪一个;由图3和图4我们知道S3C2440的时钟源来自于晶体振荡器,又由图5知道晶体振荡器的频率为12MHz。
|
|
|
|
3、S3C2440时钟体系结构是如何对时钟进行倍频和分频?
答:由图2可知确定后的时钟频率经由MPLL\UPLL锁相环进行倍频或分频。
4、S3C2440内有哪些时钟、它们各自工作在哪些地方以及他们允许的最高频率是多少?
答:由图2我们可以得知S3C2440时钟体系结构中分为MPLLin CLK、FCLK、HCLK、PCLK、UCLK和RTC XTAL CLK,他们分别工作于不同的设备。
MPLLin CLK为源时钟可工作于所有设备;
FCLK为CPU时钟工作于ARM920T;
HCLK为高速时钟工作于Memory Controller、Interrupt Controller、Nand Flash Controller等高速设备;
PCLK为外设时钟工作于UART、SPI、I2C等慢速外围设备;
UCLK为USB时钟主要工作于USB设备;
RTC XTAL CLK为实时时钟。
而在这里我们主要设置的是FCLK、HCLK和PCLK,由S3C2440芯片手册得知FCLK<=400MHz,HCLK<=136MHz,PCLK<=68MHz。
5、我们想要得到的时钟频率有哪些?
答:我们想要得到的是FCLK=400MHz、HCLK=100MHz、PCLK=50MHz。
6、为得到我们需要的时钟频率,我们该设置哪些寄存器以及怎么设置?
答:通过查看S3C2440芯片手册得知需要设置MPLLCON寄存器以及CLKDIVN寄存器,由图6、图7和图8知若要使FCLK=400MHz、HCLK=100MHz、PCLK=50MHz,我们需要设置MPLLCON寄存器中的MDIV=92,PDIV=1,SDIV=1;CLKDIVN寄存器中的HDIVN=0b10,PDIVN=1;
|
|
|
【注意】
- 为确保锁相环能正常工作,我们应将LOCKTIME寄存器的默认值写进LOCKTIME寄存器,其默认值如图9,同时在图9中我们也得知MPLL锁相环输出时钟的计算方法。。
|
- 如图10所示,其基本意思就是当HDIVN不为0时我们必须用图10中的指令将CPU的总线模式从快速总线模式更改为异步总线模式,否则的话CPU将由HCLK操作,这将极大地降低CPU的效率。
|
7、编写时钟配置代码
其中主要用来配置时钟的是11~46行。
.text
.global _start
_start:
/* 关闭看门狗 */
ldr r0 , =0x53000000
ldr r1, =0
str r1, [r0]
/* 设置 MPLL,使 FCLK : HCLK : PCLK = 400M : 100M : 50M */
/* 设置 LOCKTIME(0x4C000000) = 0xFFFFFFFF */
ldr r0, =0x4C000000
ldr r1, =0xFFFFFFFF
str r1, [r0]
/* 设置 CLKDIVN(0x4C000014),使HDIVN = 0b10, PDIVN = 1
* CLKDIVN = 5
*/
ldr r0, =0x4C000014
ldr r1, =5
str r1, [r0]
/* 因为HDIVN不为0,
* 故将CPU总线模式从快速总线模式更改为异步总线模式(S3C2440不支持同步总线模式)
*/
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000 //R1_nF:OR:R1_iA
mcr p15,0,r0,c1,c0,0
/* 设置 MPLLCON(0x4C000004), MDIV = 92, PDIV = 1, SDIV = 1
* 使 tFCLK : tHCLK : tPCLK = 1 : 2 : 8
* m = (MDIV + 8) = 92 + 8 =100
* p = (PDIV + 2) = 1 + 2 = 3
* s = SDIV = 1
* FCLK = 2 * m * Fin / (p*2^s)
* = 2 * 100 * 12M / 3*2^1),
* = 400MHz
*/
ldr r0, =0x4C000004
ldr r1, =((92<<12) | (1<<4) | (1<<0))
str r1, [r0]
/* 一旦设置了PLL,CPU就会锁定lock time 直到PLL输出稳定
* 然后CPU工作于新的频率FCLK
*/
/* 设置内存,SP栈
* 先判断是nor启动还是nand启动
* 可以nand flash进行写,它相当于ram,但不能对nor flash进行写
* 往nand flash的0地址写0,随后判断0地址是否为0
* 若为0,则为nand启动
* 否则则为nor启动
*/
mov r1, #0
ldr r0, [r1] /* 读原来的值 */
str r1, [r1] /* 往0地址写0 */
ldr r2, [r1] /* 读写后的值 */
cmp r1, r2;
ldr sp, = 0x40000000 + 4096 /* nor启动 */
ldreq sp, = 4096 /*如果相等则为 nand启动 */
streq r0, [r1]
bl main
halt: /* 死循环 */
bl halt