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

s3c2440系统时钟详解

程序员文章站 2024-02-22 18:44:10
...
一、S3C2440系统时钟体系

S3C2440的时钟控制逻辑可以外接晶振,然后通过内部电路产生时钟源;也可以直接使用内部提供的时钟源,他们通过引脚的设置来选择。时钟逻辑给整个芯片提供了3中时钟:FCLK用于CPU核、HCLK用于AHB总线上设备,比如CPU核、存储器控制器、中断控制器、LCD控制器、DMA控制器和USB主机模块等;PCLK用于用于APB总线上的设备,比如看门狗、IIS、I2C、PWM定时器、MMC接口、ADC、UART、GPIO、RTC和SPI等。
AHB(Advanced High performance Bus)系统总线总线主要用于高性能模块(如CPU、DMA和DSP等);APB(Advanced Peripheral Bus)外围总线主要用于低宽带的周边外设之间的连接(UART、I2C等)。
S3C2440CPU核的工作电压为1.8V时,主频可以达到200MHZ;工作电压为2V时,主频可以达到266MHZ;工作电压为1.2V时,主频可以达到300MHZ;工作电压为1.3V时,主频可以达到400MHZ。通常外接的晶振频率很低,需要通过时钟控制逻辑的PLL提高系统时钟。


S3C2440有两个PLL:MPLL、UPLL。UPLL专用于USB设备,MPLL用于设置FCLK、HCLK、PCLK。他们的设置方法相似,本文以MPLL为例。

上电时,PLL没被启动,FCLK就等于外部的时钟,称为Fin,若要提高系统时钟,需要软件来启动PLL。j结合图来具体介绍

s3c2440系统时钟详解

(1)、上电几毫秒后,晶振(图中的OSC)输出稳定,FCLK等于Fin(晶振频率),nRESET信号恢复高电平后,CPU开始执行指令。
(2)、可以在程序开头启动MPLL,设置MPLL的几个寄存器后,需要等待一段时间(Lock Time),MPLL的输出才稳定。在这段时间内,FCLK停震,CPU停止工作。Lock Time时间的长短由LOCKTIME寄存器设定。
(3)、Lock Time之后,MPLL输出正常,CPU工作在新的FCLK下。
FCLK、HCLK、PCLK的比例是可以改变的,设置他们三个的比例,启动MPLL只需要设置3个寄存器,对于S3C2440来说,他们之间的比例还需要额外设置一个寄存器。

二、系统时钟寄存器设置


1、LOCKTIME寄存器

s3c2440系统时钟详解

用于设置Lock Time的长度,前面说过,MPLL启动之后需要等待一段时间,使得其输出稳定。S3C2440中,位[31:16]用于UPLL,位[15:0]用于MPLL。一般而言,使用它的默认值即可,S3C2440中默认值是0xFFFFFFFF。

(2)、MPLLCON寄存器:用于设置FCLK与Fin的倍数

s3c2440系统时钟详解

位[19:12]的值称为MDIV,位[9:4]的值称为PDIV,位[1:0]的值称为SDIV。FCLK与Fin的关系有如下的计算公式

s3c2440系统时钟详解

当设置MPLLCON后,相当于上图中的“首先使用软件设置PLL”,Lock Time 就被自动的插入。Lock Time之后,MPLL输出稳定,CPU工作新的FCLK下。

(3)、CLKDIVN寄存器:用于设置FCLK、HCLK、PCLK三者的比例
对于S3C2440,这个寄存器格式如下图:

s3c2440系统时钟详解

对于S3C2440的一些时钟比例,还需要额外设置一个寄存器CAMDIVN寄存器:

s3c2440系统时钟详解

HDIVN为CLKDIVN寄存器的位[2:1],PDIVN为位[0]。

三、时钟设置程序

clock_init.c

#define S3C2440_MPLL_200MHZ     ((0x5c<<12)|(0x01<<4)|(0x02))
/*
 * 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV
 * 有如下计算公式:
 *  S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)
 * 对于本开发板,Fin = 12MHz
 * 设置CLKDIVN,令分频比为:FCLK:HCLK:PCLK=1:2:4,
 * FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
 */
void clock_init(void)
{
    // LOCKTIME = 0x00ffffff;   // 使用默认值即可
    CLKDIVN  = 0x03;            // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1

    /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
__asm__(
    "mrc    p15, 0, r1, c1, c0, 0\n"        /* 读出控制寄存器 */ 
    "orr    r1, r1, #0xc0000000\n"          /* 设置为“asynchronous bus mode” */
    "mcr    p15, 0, r1, c1, c0, 0\n"        /* 写入控制寄存器 */
    );

   
   MPLLCON = S3C2440_MPLL_200MHZ;  /* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */