欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

S3C2440芯片的时钟体系结构

程序员文章站 2022-06-08 21:30:47
...

从零开始写一个简单的bootloader(1)

 

下图是S3C2440芯片的整体架构图:

S3C2440芯片的时钟体系结构

其中,

AHB BUS为高速设备的总线,H即为high的意思。

APB BUS为低速设备的总线,P为英文单词peripheral(外围设备)。

不同的总线,挂载在上面的设备运行的频率肯定是不一样的,在我们这款S3C2440芯片中:

S3C2440芯片的时钟体系结构

Fclk就是CPU的运行频率,最高可达400MHz

Hclk为高速设备的运行频率,最高可达136MHz

Pclk为低速设备的运行频率,最高可达68MHz

那么这三种时钟频率是怎么得到的,他们又是什么关系呢?

        S3C2440这款芯片的时钟源为一个12M的晶振,再配合PLL(锁相环)就可以获得相应的频率。这里我们不对PLL的工作原理做详细,有兴趣的可以自查(好吧,我承认我不会)。下面给出一个时钟频率生成的结构图:

S3C2440芯片的时钟体系结构

图中有些名词我们先解释一下:

  1. OSC是晶振的意思
  2. OM为选择器,可以设置它选择不同的时钟源S3C2440芯片的时钟体系结构                                                        其中,OM[3:2]的设置可以获得不同的时钟来源,晶振(crystal)或者外部的时钟源(EXTCLK)
  3. MPLL:main PLL
  4. UPLL:USB PLL(用于usb设备)

上面的时钟频率生成图虽然看起来画了很多的东西,但是我们可以总结为一个简单的流程,就是:

 

晶振 ->  MPLL  -> FCLK  -> CPU

      |            |

      |            |(HDIV) -> HCLK ->AHB总线->nand flash控制器、

      |            |

      |            |(PDIV)->PCLK ->APB总线->I2C、GPIO、SPI等

      |

      | -> UPLL -> USB  

 

        我们可以得到,Fclk是由晶振和MPLL得到的,而Fclk是用于CPU运行的频率。Fclk再经过分频器(HDIV和PDIV)之后就可以得到Hclk和Pclk。

        下面我大概说明一下获得Fclk的一个过程:

S3C2440芯片的时钟体系结构

当power变成高电平,也就是上电后:

  1. 复位引脚nRESET先维持一段时间(n代表低电平有效),等各种状态稳定后,才被拉高

  2. 上电后初始阶段,FCLK=晶振频率

  3. nRESET被拉高后,CPU开始运行,PLL锁存OM[3:2]的值

  4. 在lock time期间,CPU停止运行。PLL开始工作

  5. Lock time后,FCLK等于PLL输出的新时钟,CPU也开始工作

       到这里,我们就大概知道这三种频率是怎么来的,以及他们的关系是什么样的了。虽然原理讲了一大堆,但是在实际的编程中,也就是设置一些寄存器的工作,了解原理只是为了我们更好的读懂芯片手册并设置寄存器。

       这里我们举个例子,看一下怎么去设置寄存器,得到我们想要的时钟频率。假如我们想得到的时钟频率比是:

                                             FCLK:HCLK:PCLK = 400MHz : 100MHz : 50MHz

(1)

时钟频率比为1:4:8,所以我们要设置CLKDIVN寄存器为b0101=0x5(默认CAMDIVN[9]=0)

S3C2440芯片的时钟体系结构

(2)

由芯片给出的Fclk计算公式是:

S3C2440芯片的时钟体系结构

Mpll就是我们要求的Fclk,Fin是晶振的频率12MHz,那么MDIV、PDIV和SDIV的值怎么得到呢?我们看下面的表格可以看出来,要得到12MHz的输入和400MHz的输出时,MDIV=92, PDIV=SDIV=1。那么MOLLCON寄存器的值就是(92<<12) | (1<<4) | (1<<0)

S3C2440芯片的时钟体系结构

S3C2440芯片的时钟体系结构

(3)

至于locktime的设置,我们用默认值就好了(一般不确定怎么设置的时候。用默认值就好了)

S3C2440芯片的时钟体系结构

 

根据上面的三个步骤,我们汇总一下可以到下面的代码:

/* 2.设置时钟 */
	/*设置MPLL, FCLK:HCLK:PCLK = 400MHz : 100MHz : 50MHz*/
	/*为了保险先初始化一下locktime*/
	ldr r0, =0x4C000000
	ldr r1, =0xFFFFFFFF
	str r1, [r0]

	/*设置CLKDVIN:
	  *HDIVN[2:1] :    10  -  HCLK=FCLK/4
	  *PDVIN[0]    :     1   -   PCLK=HCLK/2
	  */
	ldr r0, =0x4C000014
	ldr r1, =0x5
	str r1, [r0]

	/*设置CPU为异步模式*/
	mrc p15,0,r0,c1,c0,0
	orr r0,r0,#0xc0000000  //R1_nF:OR:R1_iA 
	mcr p15,0,r0,c1,c0,0

	/*
	  *Mpll = (2 * m * Fin) / (p * 2S) 
	  *m = (MDIV + 8), p = (PDIV + 2), s = SDIV
	  *当Fin=12MHz,若要 Mpll=400MHz,则有MDIV=92, PDIV=SDIV=1
	  */
	ldr r0, =0x4C000004
	ldr r1, =(92<<12) | (1<<4) | (1<<0)
	str r1, [r0]

	/*一旦设置了PLL,就会锁定locktime直到PLL输出稳定
	  *然后CPU工作于新的频率
	  */