嵌入式入门2(时钟体系)

318 阅读3分钟

S3C2440是一个SOC(System On Chip),它支持多种外设。其芯片手册第1章的BLOCK DIAGRAM图就对所支持的外设进行了列举:

image.png

可以把该图分为上中下三部分:

  • 最上面的ARM920T是CPU核心部分,工作于FCLK;
  • 中间的设备挂载在AHB总线上,它们对性能要求较高,如LCD、Camera等,工作于HCLK;
  • 最下面的是一些对性能要求不那么高的低速设备,在APB BUS,P即为Peripheral之意,工作在PCLK。

在参考手册的特性里介绍了这3个时钟的最高工作频率:

Fclk最高400MHz
Hclk最高136MHz
Pclk最高68MHz

而这3种频率的时钟是如何得到的呢?我们可以找到芯片手册第7章的Clock Generator Block Diagram图:

image.png

该图可简化为下图:

image.png

其中PLL表示锁相环,DIVN表示分频器。通过MPLL产生的时钟信号通过分配器分别产生FCLK、HCLK和PCLK三种频率时钟信号。而通过UPLL产生的时钟专门供给USB模块,频率为48MHZ。

FCLK提供给ARM920T。
HCLK提供给AHB总线,用于一些高速外设,如:ARM920T,存储器控制器,中断控制器,LCD 控制器,DMA 和 USB 主机模块。
PCLK提供给APB总线,用于一些慢速外设,如 WDT,IIS,I2C,PWM 定时器,MMC/SD 接口,ADC,UART,GPIO,RTC 和SPI。

这时,我们可以清楚的知道:

S3C2440时钟源可以采用OSC(晶振),也可以采用EXTCLK(外接时钟源),由OM[3:2]决定。

当设备上电时,时钟源通过OM[3:2]两个pin脚来决定,可选值如下:

image.png

我们查看JZ2440的电路图,发现OM[3:2]两个引脚直接接地,表明主时钟源和USB时钟源都是来自晶振。

image.png

JZ2440电路图,也明确显示了板载晶振为12M。

image.png

至此,我们已确定输入时钟为12MHZ,后续只需要设置P[5:0]、M[7:0]、S[1:0]寄存器,决定MPLL/UPLL的输出频率。

image.png

开机复位时序图,流程如下:

  • 1、设备上电FCLK开始工作,复位芯片等待电源稳定,才输出高电平。
  • 2、电源稳定后,复位芯片变成高电平,PLL锁存OM[3:2]的值,CPU开始运行。
  • 3、开始设置PLL,设置后,在Lock Time期间,FCLK停止起振,CPU停止运行。
  • 4、Lock Time结束,FCLK就变成PLL输出的新时钟,CPU开始运行。

image.png

image.png

通过设置MDIV=92,PDIV=1,SDIV=1,使得MPLL输出400MHz。

image.png

然后通过配置CLKDIVN寄存器,使FCLK=400MHzHCLK=100MHzPLCK=50MHz

start.S

.text
.global _start

_start:

    /* 关闭看门狗 */
    ldr r0, =0x53000000
    mov r1, #0x0
    str r1, [r0]

    // LOCKTIME(0x4C000000) = 0xFFFFFFFF
    ldr r0, =0x4C000000
    ldr r1, =0xFFFFFFFF
    str r1, [r0]

    // 设置CLKDIVN(0x4C000014) = 0X5, tFCLK:tHCLK:tPCLK = 1:4:8
    // 让FCLK : HCLK : PCLK = 400m : 100m : 50m
    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

    /* 设置FCLK工作在400M
     * MPLLCON(0x4C000004) = (92<<12)|(1<<4)|(1<<0) 
     *  m = MDIV+8 = 92+8=100
     *  p = PDIV+2 = 1+2 = 3
     *  s = SDIV = 1
     *  FCLK = 2*m*Fin/(p*2^s) = 2*100*12/(3*2^1)=400M
     */
    ldr r0, =0x4C000004
    ldr r1, =(92<<12)|(1<<4)|(1<<0)
    str r1, [r0]

    /* 一旦设置PLL, 就会锁定lock time直到PLL输出稳定
     * 然后CPU工作于新的频率FCLK
     */
	
    ldr sp, =0x40000000+4096 /* NOR启动 */

    /*调用main*/
    bl main

halt:
    b halt