目录
1.系统的组成
2.系统时钟的来源
3.如何编程控制
4.编程设置系统时钟
S3C2440是一块SOC芯片,里面有CPU和外设等,外设分为高速总线(AHB)和低速总线(APB),在这些总线上挂载这很多设备,如下图所示,这些设备除了电源,还有一个必不可少的就是时钟,而我们需要探讨的正是这些时钟的来源。
查看芯片数据手册,可以看到各个时钟源可以设置的最大频率如下:
可以看到Fclk最大可达:400MHz
系统时钟的来源是外部的晶振,可以通过查看原理图知道系统的晶振是12M的
那如何得到400M这个高的主频呢?
当然是通过系统芯片内部有一些转换电路来完成的,而且还是可编程的,其中最重要的还是锁相环(PLL)。
查看时钟的系统框图:
注意点:
时钟的来源是通过 OM[3:2] 这两个位来控制的,在芯片手册这两位的含义如下:
当设置为0b00时,MPLL和UPLL的时钟来源都是外部晶振,通过原理图可知,这两个外部引脚全部被拉低,因此默认是使用外部的12MHz晶振。
通过系统框图可知,系统时钟来源已经默认被设置为外部12M的晶振,所以需要设置的就是MPLL(锁相环),经过锁相环之后,相当于外部竞争倍频了,倍频后的时钟就是系统时钟(Fclk),系统时钟经过分频系数(HDIVN)的到高速总线时钟(AHB),以及系统系统时钟经过分频系数(PHDIVN)的到外设时钟(APB).
3.1、系统时钟设置的时序
设置系统时钟: Fclk =400M 、Hclk = 100M 、Pclk = 50 M
设置步骤:
1).设置CLKDIVN寄存器,使 Hclk = Fclk / 4,Pclk = Fclk / 8;
2).设置MPLLCON寄存器,使 Fclk =400Mhz
提醒:上边的时序中有一个LOCK TIME时间的设置,默认是
为了保险可以重新设置一下这个寄存器的值为:0xFFFFFFFF
步骤一: 设置CLKDIVN控制寄存器
加入设置系统主频Fclk = 400M,那么设置寄存器CLKDIVN[2:1] = 0b10,CLKDIVN[0] = 0b1,即可
也就是:往寄存器CLKDIVN(0x4C000014)写值0x5
步骤二:设置MPLLCON寄存器
这个是设置MPLL的倍频系数,最终产生Fclk的时钟,也就是这只原理框图的下图部分的值:
而这个数值,官方文档也有提供给我们参考值,如下:
加入外部晶振是12MHz,需要设置Fclk的频率为400Mhz,那么MDIV需要设置为92,PDIV设置为 1 ,SDIV设置为1.
根据公式计算可得下面的结果:
从编程的角度来讲就是:
往寄存器MPLLCON(0x4C000004) 的MPLLCON[19:12]=92 ,MPLLCON[9:4]=1,MPLLCON[1:0]=1.
注意事项:
1).编写汇编代码:
如下:
.text
.global _start
_start:
/*关闭看门狗*/
ldr r0 ,=0x53000000
ldr r1 ,=0
str r1 ,[r0]
/*设置MPLL=400Mhz*/
/*LOCKTIME(0x4C000000) = 0xFFFFFFFF*/
ldr r0 ,=0x4C000000
ldr r1 ,=0xFFFFFFFF
str r1 ,[r0]
/*设置CLKDIVN(0x4C000014)=0x5*/
ldr r0, =0x4C000014
ldr r1, =0x5
str r1, [r0]
/*使CPU总线工作与异步模式*/
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000
mcr p15,0,r0,c1,c0,0
/*往寄存器MPLLCON(0x4C000004) 的MPLLCON[19:12]=92(0x5c) ,MPLLCON[9:4]=1,MPLLCON[1:0]=1.*/
ldr r0, =0x4C000004
ldr r1, =(0x5c<<12)|(1<<4)|(1<<0)
str r1, [r0]
/*设置内存:sp 栈*/
/*自动分辨是nand/nor启动方式*/
/*思路:因为nand是支持直接读取的,不需要什么
格式,而nor可以任意写,但是读取需要特定的
格式,若一开始往0地址写入一个值,然后读出来
如果读取的值和写入的值是一致的,说明是nand启动
否则是nor启动*/
mov r1 ,#0 //r1赋值为0
ldr r0 ,[r1] //读取0地址的值,以便后面恢复
str r1 ,[r1] //把0写入0地址里面
ldr r2 ,[r1] //从0地址读取值到r2
cmp r1 ,r2 //判断r1和r2是否相等,相等为nand启动
ldr sp ,=0x40000000+4096 //假设为nor启动
moveq sp, #4096 //相当为nand启动,重新设置sp
streq r0,[r1] //恢复nand中0地址的值
bl main
halt:
b halt
这样就完成了对系统时钟的设置,并且Fclk = 400M, Hclk=100M,Pclk=50M.