按照S5PV210的官方手册使用C语言配置系统时钟--实例分析

按照S5PV210的官方手册使用C语言配置系统时钟

                                                             
--参考朱有鹏ARM裸机编程

我需要完成的目标就是设置系统时钟为官方手册一样的样子

了解一下S5PV210的时钟系统是怎么配置的?以便于在其他的处理器也进行这种配置。

1、实验的目标:


这里的数据手册可能比较老,我们设置为ARMCLK:1GHz比较好


2、S5PV210的时钟框图的理解:


(1)、由图中可以知道,我们可以通过很多地方得到外部晶振。

      210的晶振是统一的24MHZ,我们使用XUSBXT1这个端口的信息。

(2)、里面有几个MUX梯形的东西,就是选择信号来源的地方,

可以进行编程选择。

(3)、我们目标是启动这么多外设的时钟,但是我们外设的时钟是怎么来的?

答案是通过外部的24MHZ,但是这个频率太慢了,所以我们需要倍频进行处理。

也就是通过这些PLL锁相环进行处理。

(4) 举一个例子:我们怎么得到PCLK_MSYS这个时钟的频率:

第一,我们是通过XUSBxt1从外部进来一个24MHZ

第二,我们通过选择开关1,进入得到FINPLL信号

第三,我们通过APLL进行锁相环的倍频处理,此时如果不在MUXapll进行选择开关1的话,

那么信号就无法传输到后面的程序

第四,我们需要经过一个名叫,MUXMSYS的选择开关,此时会经过一个分频器DIVAPLL

此时,如图所示,我们得到的ARMCLK的主频的时钟

第五,我们经过一个分频器DIVHCLKM分频,可以按照我们的要求分频出一个

HCLK_MSYS这个信号的时钟

第六:最后也是我们的目标的频率,PCLK_MSYS,我们通过DIVPCLKM


设置我们ARM的主频:我们需要设置的寄存器就是APLL的锁相环:


ARMCLK:

由数据手册的记录中可以知道,我们需要通过计算公式得到:

FOUT = 1000MHZ  ,也就是说我们需要知道MDIV, PDIV, SDIV

FIN就是我们210规定的24MHZ;

根据数据手册的推荐,我们可以知道

MDIV = 125,PDIV = 3, SDIV=1的时候可以得到这个1GHz的主频


就这样我们可以通过上面来配置S5PV210的主频,接下来所有的分频频率都可以通过分频器的寄存器

来得到我们想要的频率:

可以从上面的图可以得出:DIVAPLL = 1,也就是它压根没有进行分频


但是我们HCLK_MSYS的目标的频率是200MHZ,所以我们需要

主频进行5分频才可以得到,所以DIVHCLK的分频器需要进行5分频


同理可以得到PCLK_CLK需要100MHZ的频率,所以DIVPCLK需要从HCLKCLK进行2分频可以得到。


这是配置有关时钟的寄出器的代码可以进行参考,但是关键还是读懂前面的那张图

//clock.c
// 时钟控制器基地址
#define ELFIN_CLOCK_POWER_BASE		0xE0100000	

// 时钟相关的寄存器相对时钟控制器基地址的偏移值
#define APLL_LOCK_OFFSET		0x00		
#define MPLL_LOCK_OFFSET		0x08

#define APLL_CON0_OFFSET		0x100
#define APLL_CON1_OFFSET		0x104
#define MPLL_CON_OFFSET			0x108

#define CLK_SRC0_OFFSET			0x200
#define CLK_SRC1_OFFSET			0x204
#define CLK_SRC2_OFFSET			0x208
#define CLK_SRC3_OFFSET			0x20c
#define CLK_SRC4_OFFSET			0x210
#define CLK_SRC5_OFFSET			0x214
#define CLK_SRC6_OFFSET			0x218
#define CLK_SRC_MASK0_OFFSET	0x280
#define CLK_SRC_MASK1_OFFSET	0x284

#define CLK_DIV0_OFFSET			0x300
#define CLK_DIV1_OFFSET			0x304
#define CLK_DIV2_OFFSET			0x308
#define CLK_DIV3_OFFSET			0x30c
#define CLK_DIV4_OFFSET			0x310
#define CLK_DIV5_OFFSET			0x314
#define CLK_DIV6_OFFSET			0x318
#define CLK_DIV7_OFFSET			0x31c

#define CLK_DIV0_MASK			0x7fffffff

// 这些M、P、S的配置值都是查数据手册中典型时钟配置值的推荐配置得来的。
// 这些配置值是三星推荐的,因此工作最稳定。如果是自己随便瞎拼凑出来的那就要
// 经过严格测试,才能保证一定对。
#define APLL_MDIV      	 		0x7d		// 125
#define APLL_PDIV       		0x3
#define APLL_SDIV       		0x1

#define MPLL_MDIV				0x29b		// 667
#define MPLL_PDIV				0xc
#define MPLL_SDIV				0x1

#define set_pll(mdiv, pdiv, sdiv)	(1<<31 | mdiv<<16 | pdiv<<8 | sdiv)
#define APLL_VAL			set_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV)
#define MPLL_VAL			set_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV)

//这里是我们需要编写代码的地方:
#define set_pll(mdiv, pdiv, sdiv)  (1<<31 | mdiv<<16 | pdiv<<8 | sdiv)
#define APLL_VAL    set_pll(APLL_MDIV,APLL_PDIV,APLL_SDIV)
#define MPLL_VAL    set_pll(MPLL_MDIV,MPLL_PDIV,MPLL_SDIV)

//寄存器地址的定义:
#define REG_CLK_SRC0    (ELFIN_CLOCK_POWER_BASE + CLK_SRC0_OFFSET)
#define REG_APLL_LOCK   (ELFIN_CLOCK_POWER_BASE + APLL_LOCK_OFFSET)
#define REG_MPLL_LOCK	(ELFIN_CLOCK_POWER_BASE + MPLL_LOCK_OFFSET)
#define REG_CLK_DIV0	(ELFIN_CLOCK_POWER_BASE + CLK_DIV0_OFFSET)
#define REG_APLL_CON0	(ELFIN_CLOCK_POWER_BASE + APLL_CON0_OFFSET)
#define REG_MPLL_CON	(ELFIN_CLOCK_POWER_BASE + MPLL_CON_OFFSET)

//定义一个东西取寄存器内部的内容:
#define rREG_CLK_SRC0   (*(volatile unsigned int *)REG_CLK_SRC0)
#define rREG_APLL_LOCK  (*(volatile unsigned int *)REG_APLL_LOCK)
#define rREG_MPLL_LOCK	(*(volatile unsigned int *)REG_MPLL_LOCK)
#define rREG_CLK_DIV0	(*(volatile unsigned int *)REG_CLK_DIV0)
#define rREG_APLL_CON0	(*(volatile unsigned int *)REG_APLL_CON0)
#define rREG_MPLL_CON	(*(volatile unsigned int *)REG_MPLL_CON)


void clock_init(void)
{
    //1、设置各种时钟开关,暂时不使用PLL
	rREG_CLK_SRC0 = 0x0;
	
	//2、设置锁定时间,使用默认值就可以了
	//设置PLL后时钟从FIN提升到目标频率,需要一定的时间,集锁定时间
	rREG_APLL_LOCK = 0x0000ffff;
	rREG_MPLL_LOCK = 0x0000ffff;
	
	//3、设置时钟的分频系数
	//清除bit[0~31]
	rREG_CLK_DIV0 = 0x14131440;
	
	//4、设置PLL
	rREG_APLL_CON0 = APLL_VAL;	
	rREG_MPLL_CON = MPLL_VAL;

    //5/设置各种时钟开关,使用PLL
	rREG_CLK_SRC0 = 0x10001111;

}



















  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值