6.ARM(S3C2440)芯片时钟体系

目录

1.系统的组成

2.系统时钟的来源

3.如何编程控制

 4.编程设置系统时钟


 

1.系统的组成

S3C2440是一块SOC芯片,里面有CPU和外设等,外设分为高速总线(AHB)和低速总线(APB),在这些总线上挂载这很多设备,如下图所示,这些设备除了电源,还有一个必不可少的就是时钟,而我们需要探讨的正是这些时钟的来源。

6.ARM(S3C2440)芯片时钟体系_第1张图片

查看芯片数据手册,可以看到各个时钟源可以设置的最大频率如下:

可以看到Fclk最大可达:400MHz 

6.ARM(S3C2440)芯片时钟体系_第2张图片


2.系统时钟的来源

系统时钟的来源是外部的晶振,可以通过查看原理图知道系统的晶振是12M的

6.ARM(S3C2440)芯片时钟体系_第3张图片

那如何得到400M这个高的主频呢?

当然是通过系统芯片内部有一些转换电路来完成的,而且还是可编程的,其中最重要的还是锁相环(PLL)。

查看时钟的系统框图:

6.ARM(S3C2440)芯片时钟体系_第4张图片

注意点:

时钟的来源是通过  OM[3:2] 这两个位来控制的,在芯片手册这两位的含义如下:

6.ARM(S3C2440)芯片时钟体系_第5张图片

当设置为0b00时,MPLL和UPLL的时钟来源都是外部晶振,通过原理图可知,这两个外部引脚全部被拉低,因此默认是使用外部的12MHz晶振。

6.ARM(S3C2440)芯片时钟体系_第6张图片


3.如何编程控制

通过系统框图可知,系统时钟来源已经默认被设置为外部12M的晶振,所以需要设置的就是MPLL(锁相环),经过锁相环之后,相当于外部竞争倍频了,倍频后的时钟就是系统时钟(Fclk),系统时钟经过分频系数(HDIVN)的到高速总线时钟(AHB),以及系统系统时钟经过分频系数(PHDIVN)的到外设时钟(APB).

3.1、系统时钟设置的时序

6.ARM(S3C2440)芯片时钟体系_第7张图片


 4.编程设置系统时钟

设置系统时钟: Fclk =400M 、Hclk = 100M 、Pclk = 50 M

设置步骤:

1).设置CLKDIVN寄存器,使 Hclk = Fclk / 4,Pclk = Fclk / 8;

2).设置MPLLCON寄存器,使 Fclk =400Mhz

提醒:上边的时序中有一个LOCK TIME时间的设置,默认是 

6.ARM(S3C2440)芯片时钟体系_第8张图片

为了保险可以重新设置一下这个寄存器的值为:0xFFFFFFFF

步骤一: 设置CLKDIVN控制寄存器

  • CLKDIVN寄存器描述:

加入设置系统主频Fclk = 400M,那么设置寄存器CLKDIVN[2:1] = 0b10,CLKDIVN[0] = 0b1,即可

也就是:往寄存器CLKDIVN(0x4C000014)写值0x5

6.ARM(S3C2440)芯片时钟体系_第9张图片

步骤二:设置MPLLCON寄存器

  • MPLLCON寄存器描述

6.ARM(S3C2440)芯片时钟体系_第10张图片

这个是设置MPLL的倍频系数,最终产生Fclk的时钟,也就是这只原理框图的下图部分的值:

6.ARM(S3C2440)芯片时钟体系_第11张图片

而这个数值,官方文档也有提供给我们参考值,如下:

加入外部晶振是12MHz,需要设置Fclk的频率为400Mhz,那么MDIV需要设置为92,PDIV设置为 1 ,SDIV设置为1.

6.ARM(S3C2440)芯片时钟体系_第12张图片

根据公式计算可得下面的结果:

6.ARM(S3C2440)芯片时钟体系_第13张图片 

从编程的角度来讲就是:

往寄存器MPLLCON(0x4C000004) 的MPLLCON[19:12]=92 ,MPLLCON[9:4]=1,MPLLCON[1:0]=1.


注意事项:

6.ARM(S3C2440)芯片时钟体系_第14张图片


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.


 

 

你可能感兴趣的:(Linux裸机开发学习笔记)