基于S3C6410的ARM11学习(十) 时钟初始化

发布者:ww313618最新更新时间:2021-02-20 来源: eefocus关键字:S3C6410  ARM11  时钟初始化 手机看文章 扫描二维码
随时随地手机看文章

之前已经用led验证了核心初始化的代码是可以用的了。接着就要进行到下一步,这一步就是时钟初始化,因为在时钟初始化之前,CPU的系统时钟都是跑在外部晶振12M上的,这速度也太慢了,S3C6410可是跑在600多M时钟上的。所以我们就需要对时钟进行配置,将系统时钟调高。


这时候,其实是可以初始化C所用环境,然后用c语言来写,不过为了练习编写汇编代码,就使用汇编代码来写了。


S3C6410的时钟是挺复杂的。比51单片机的时钟要是要复杂多了去了。下面是时钟的框图。

clip_image002

S3C6410共有3个PLL。PLL是时钟倍频用的。我使用的OK6410外部晶振是12M的。但是CPU的时钟是可以跑600多M的,这怎么实现的了。就是靠PLL来实现的。PLL对输入的频率可以进行倍频,倍频的倍数可以通过软件配置,所以才可以用外部的12M晶振给CPU提供600M的时钟。


第一个APLL。这个PLL是提供系统时钟的。就是供给ARM11核的时钟

第二个MPLL。这个PLL是提供AHB,APB时钟的。

第三个EPLL。这个PLL是提供某些外设的时钟。


在这里,我们只关心APLL和MPLL的配置。下图是默认的时钟配置

clip_image004

红色标明的线是说明该时钟走的路线。图中的选择器,默认为都是选择0那一端的。所以在开始的时候,

1、系统时钟:外部晶振直接通过MUXapll和第二个选择器,所以ARMCLK时钟就是外部晶振时钟12M。

2、AHB,APB总线:外部晶振直接通过MUXmpll和第二个选择器,第三个选择器,后面的CLKGEN不分频的,所以AHB和APB时钟也是12M。


下面我们就要改变这条时钟路线,并配置PLL。改变的路线如下所以

clip_image006

1、系统时钟:从外部晶振到APLL,APLL将外部时钟倍频到时钟1。在通过选择器,在通过第二个选择器,分频不分频,所以ARMCLK时钟就是时钟1。


2、 AHB,APB总线时钟:从外部晶振到MPLL。将MPLL倍频到时钟2。在通过第一个选择器,第二个选择器,第三个选择器,CLKGEN进行分频,所以AHB/AXI总线时钟就是时钟3。PCLK时钟就是时钟4


知道了时钟的走向,但是时钟1,时钟2,时钟3,时钟4应该是多少了。

clip_image008

上图,是S3C6410手册中提供的几个频率值。那我们到底是使用哪一个了。这个时候,就去看uboot,看他配置的哪个时钟。


查阅,uboot代码,得知,配置的APLL时钟是533M,MPLL是533M。时钟1是533M,时钟2是533M,时钟3是133M,时钟4是66M。


即PCLK:AHBCLK:APBCLK = 533:133:66 = 1:4:8


知道了这些参数,就可以去写程序配置了。不过,在写程序之前,先了解下时钟产生序列。

clip_image010

上图,是复位之后时钟产生序列。


当电源电压大于一个值后,外部晶振的频率进入到芯片中。复位无效后,系统时钟就有了,这个时候系统时钟就是外部晶振时钟。正是有了这个时钟,所以可以执行初始化的代码。然后我们就要配置PLL时钟了。这个有个锁定时间的概念。当改变PLL的输出时钟后,并不是马上时钟就产生了,而是需要一定的时间,这个时间就是锁定时间,在这个锁定时间内,输出的时钟不稳定,所以这时钟就不会进入到系统时钟去,所以这个时钟,CPU是停止工作的。当锁定时间结束后,PLL输出时钟稳定,系统时钟等于输出时钟,CPU继续工作。


配置PLL流程

1、配置PLL锁定时间(lock time)

2、配置PLL的倍频系数

3、开启PLL

4、等待锁定时间后,PLL输出频率稳定


来看看时钟初始化中用到的寄存器


1、PLL锁定时间设置寄存器

clip_image012

clip_image014

这个寄存器是配置3个PLL对应的锁定时间的。只有低16位有用。默认值是0XFFFF。这个值我们通常是不更改的,所以我们可以不用设置寄存器。


2、APLL和MPLL控制寄存器

  clip_image016

这个寄存器是用来配置PLL的倍频系数和PLL开启的。倍频系数是由寄存器中的三个参数决定。MDIV,PDIV,SDIV。设置不同的值,得到不同的倍频系数,也就得到不同的输出时钟。


计算的公式,手册中也有给,

clip_image018

不过,要去计算挺复杂的,手册中给了参考值。我们直接使用这些参考值就行了。

clip_image020

对于12M的输入时钟,如果要配置输出频率是533M。那么MDIV参数是266,PDIV参数是3,SDI参数是1。


我们是要配置PLL输出是533M的。


所以这个寄存器配置的参数就是


1<<31 | 266<<16|3<<8|1<<0


3、时钟选择控制寄存器

clip_image022

这个寄存器是用来选择时钟源的。在时钟框图中,有很多的选择器,通过选择器,可以选择不同的时钟,这儿寄存器就是配置时钟源选择哪一个。从框图中,看来我们是有两个时钟要选择的。一个是APLL后的选择器要选择APLL的输出,另一个是MPLL之后的选择器要选择MPLL的输出。从框图中知道这个和CLK_SRC寄存器的最后两位有关

clip_image024

所以,这里要配置最后两位的值都是1。选择PLL的输出。


4、时钟分频控制寄存器

clip_image026

这个是设置时钟线上某些分频器的分频。我们这里是设置ARMCLK,AHBCLK,APBCLK。


所以找到相应的位。

   clip_image028     

设置这些参数就可以得到ARMCLK,AHBCLK,APBCLK。但是这些参数怎么设置了,里面还有HCLKX2,这个是什么了。这个从手册中找到的以下这张表就明白了。

     clip_image030

这个的参数就是配置红色框部分的分频器。

1、对于1号分频器。FOUTAPL通过选择器,那么DOUTAPL时钟是533M。通过上路选择器,到达1号分频器,我们是要ARM系统时钟是在533M。所以这里分频器不分频。所以寄存器的3:0位设置为0


2、对于2号分频器。FOUTMPL通过选择器到达MOUTMPL,那么MOUTMPL时钟是533M。在通过下路的SYNCMUX选择器,在通过上路的SYNC667选择器到达2号分频器。2号分频器的输出是HCLK*2,这个时钟是给ddr使用的。这个时钟是要配置为266M。所以2号分频器二分频。所以寄存器的11:9位值为1


3、对于3号分频器。HCLK*2时钟是266M。PCLK时钟是66M。要分频4。所以寄存器的15:12位值是3


4、对于4号分频器。HCLK*2是266M,而HCLK时钟是133M。所以4号分频器要设置为2.所以寄存器的第8位值是1。


所以这个寄存器设置的值就是


3 << 12 | 1<<9 | 1 <<8 | 0<<0


上面的方法可有点慢了,手册中还有另外一张图:

clip_image032

图中说明了配置HCLK*2,PCLK,HCLK的分频器的值在寄存器的哪几位。


后面的寄存器就和初始化时钟没有多大关系了。但是在后面的时候发现有以下寄存器。

     clip_image034

从名字就可以看出,这个是门控时钟寄存器。就是控制外设功能的时钟是否使能的。不过默认为这些门控时钟都是开启的。这个和STM32是不一样的。STM32是默认为都关闭的。之前以为这ARM11没有门控时钟,原来其实ARM11是有门控时钟的。只不过默认都是开启的而已。


总结时钟初始化流程

1、设置时钟分频控制寄存器,先配置各个分频器的值

2、将CPU设置为异步模式,当AHB时钟和PCLK时钟不一样的时候,就要设置为异步模式

3、配置APLL

4、配置MPLL

5、配置时钟源选择控制寄存器,选择对应的时钟


中间有一个设置CPU为异步模式。这个是手册中规定的,这个在OTHER寄存器中设置。

clip_image036

所以,我们要将这个寄存器的第7位设置为0。同时也我们也要讲第6位设置为0.这个也是一个时钟源选择的。如下图,是选择下一路的时钟是APLL还是MPLL。

clip_image037

下面就可以写代码了,有了上面的知识后,这代码可就容易了,就是修改寄存器的值就行了。

         clip_image039

先定义所要操作寄存器的地址,然后再定义两个参数,第一个参数是配置PLL倍频系数和开启PLL的。第二个参数是配置FCLK,HCLK*2,HCLK,PCLK时钟的。这两个参数在之前已经分析过了。


下面就是初始化时钟的代码了

     clip_image041

1、先配置CLK_DIV0寄存器,配置各个分频器的分频系数。

2、将CPU设置为异步模式,就是将other寄存器的第7位写入0。首先读出这个寄存器,将值存在r1寄存器中。将r1寄存器的第七位和第八位给清零,在写入到other寄存器。

3、设置APLL

4、设置MPLL

5、设置时钟源选择,选择APLL和MPLL的输出


这样,就完成了时钟的初始化。在reset中,把上次点亮led的程序放在调用时钟初始化代码后,会发现,led闪烁的频率变高了。因为这时候已经把时钟的频率改到533M了。也就是时钟跑快了。


下面和STM32的时钟初始化:

本质上,STM32的时钟初始化和S3C6410的时钟初始化时差不多。也是配置PLL,选择时钟源。只是STM32不用将CPU设置为异步模式。而且STM32没有锁定时间,但是有一个寄存器的某一位来指示PLL输出是否准备好。


先来看看时钟树框图:

clip_image043

好大一棵时钟树。STM32支持4种时钟输入,

1:高速外部时钟,一般都是使用这个,外接的晶振一般为8M

2:高速内部时钟,8M。这个一般不用,因为内部的时钟性能不太好,时钟频率精度较差。

3:低速内部时钟,40K,这个时钟供给RTC或独立看门狗

4:低速外部时钟,32.768K,这个时钟供RTC使用。


在STM32中,只有一个PLL,这个PLL就是对外部/内部高速时钟进行倍频的,倍频最大为16倍。然后通过选择器进入到系统时钟,系统时钟最大72M,比ARM11慢多了。然后再经过各个预分频器,到各自的时钟。


在系统复位后,HSI时钟被选为系统时钟,外部时钟是被旁路的。AHB预分频值为1,APB1和APB2预分频值都是1。所以系统时钟,AHB时钟,APB1,APB2时钟都是8M。工作在这个时钟肯定是不行的了。所以就要对时钟进行配置,就要用到PLL,将时钟升上去,让系统工作在最大72M下。


时钟配置的流程:

1、打开外部时钟,配置外部时钟没有被旁路

2、等待外部时钟就绪

3、 设置AHB,APB1,APB2,ADC预分频值。

4、配置PLLTPRE和PLLSRC选择器,让外部时钟进入到PLL的输入。

5、配置PLL倍频系数,并开启

6、等待PLL锁定

7、切换SW选择器,使系统时钟选择PLL输出

8、等待PLL输出作为系统时钟


看看配置相关的寄存器

1、时钟控制寄存器

clip_image045

用来开启外部高速时钟和内部高速时钟,并可以得到时钟是否就绪。还可以开启PLL,并判断PLL是否锁定。

  clip_image047

截取一部分图。


2、时钟配置寄存器

clip_image049

配置时钟源选择,PLL倍频系数,预分频器系数

clip_image051

截取一部分图。


初始化时钟,官方库已经实现了这部分代码。下面可以来分析分析。

clip_image053

代码就是包括在SystemInit这个函数中的。这个函数在启动代码中就被调用。

clip_image055

在这个函数的中间,有调用这个SetSysClock()函数。注释也比较清楚,配置系统时钟频率,HCLK,PLCK2,PCLK1预分频系数。同时配置FLASH间隔周期和使能预先取数据功能。


进入到这个函数中,

clip_image057

通过宏判断系统时钟要设置为多少,在调用不同的函数。这个宏定义是在函数的开头部分定义的。

clip_image059

这里,把其他系统时钟宏注释,72M时钟注释去掉,就意味着将系统时钟设置为72M。


所以,就调用SetSysClockTo72()函数。

在去看这个函数实现什么。


我把这个代码中的宏,全部用他替换的值给替换掉了,这样可以知道配置什么值,就可以从寄存器去分析。代码稍微有点长,截成几部分来进行分析

clip_image061

首先定义两个无符号32位变量,变量是用__IO修饰。这个__IO,其实就是volatile的别名。

将RCC下的CR寄存器的值第16位置1.就是打开外部振荡器。


一个do while循环,就是判断外部振荡器是否就绪,其实就是判断RCC下的CR寄存器的第17位。为1就就绪,0就是没有就绪。这里多了一个变量来计数,防止如果外部晶振一直没有就绪,程序就死在这里了。

clip_image063

判断HSE就绪后,就将clip_image065

判断HSEStatus为0x1的话,说明外部晶振就绪,就接着下一步操作。下面三行代码是对FLASH操作。目前不知道这代码放在这里是干嘛的。先不管。


将RCC下的CFGR寄存器的第10位设置为1.

clip_image067

这里,就是设置AHB,APB1,APB2预分频值。AHB不分频,APB1二分频,APB2不分频。

clip_image069

将RCC下的CFGR寄存器的21位到16位设置为011101。

clip_image071

这里,就将讲HSE时钟给配置到PLL的输入,并且中间没有进行分频。在设置PLL的倍频系数是9。这样,就将输入的8M时钟给倍频到72M时钟了。


然后再开启PLL。将RCC下CR寄存器的24位设置为1.就开启了PLL。


在判断RCC下CR寄存器的25位是不是为1,为1的话,PLL就锁定了。没有的话,还没有锁定,那就等待。

clip_image073

然后选中PLL时钟作为系统时钟,通过配置CR下的CFGR最低两位为10。将PLL输出切换为系统时钟。

clip_image075

最后,要检测PLL作为系统时钟是否准备好。检测CR下的CFGR的第2和第3为是否为10.是的话,PLL输出作为系统时钟。


这样,就完成了时钟的初始化。


通过对比,还是有很多相通的地方。先设置预分频系数,在配置PLL并开启,最后配置时钟源。只是ARM11在设置预分频系数后,就要将CPU设置为异步模式。

关键字:S3C6410  ARM11  时钟初始化 引用地址:基于S3C6410的ARM11学习(十) 时钟初始化

上一篇:基于S3C6410的ARM11学习(十一) DDR初始化
下一篇:基于S3C6410的ARM11学习(九) 点亮led

推荐阅读最新更新时间:2024-11-10 11:57

深入理解ARM体系架构(S3C6410)---rtc实例
实时时钟(RTC)的主要功能是在系统掉电的情况下,利用后备电源使时钟继续运行,从而不会丢失时间信息。s3c6410内部集成了RTC模块,其内部的寄存器BCDSEC,BCDMIN,BCDHOUR,BCDDAY,BCDDATE,BCDMON和BCDYEAR分别存储了当前的秒,分,小时,星期,日,月和年,表示时间的数值都是BCD码。 S2C6410中的闰年问题: 闰年产生器基于BCDDAY,BCDMOD,BCDYEAR从而能决定每月最后的日期是28,29,30,还是31。一个8位的计数器只能表示2个BCD数据,因此不能判断 00 结尾的年份是不是闰年。例如它不能判断1900和2000是不是闰年。为了解决这个问题,S3C6410中有一
[单片机]
深入理解ARM体系架构(<font color='red'>S3C6410</font>)---rtc实例
S3C6410裸机程序,LED灯闪烁
1 /* 2 * 实现流水灯,LED1 LED2 LED3 LED4轮流被点亮熄灭 3 */ 4 5 .global _start 6 .section .text 7 8 _start: 9 10 /* 11 * set the CPU to SVC32 mode 12 */ 13 mrs r0,cpsr 14 bic r0,r0,#0x1f @ clear the last 5 bits 15 orr r0,r0,#0xd3 @ 0b11010011, set the svc mod, and disable fiq irq 16 msr cpsr,r0 17 18
[单片机]
搭建 S3C6410开发板的测试环境
S3C6410 是由三星公司推出的低功耗、高性价比的 SC ( reduced instruction set computer,精简指令集计算机〉处理器,它基于 ARMII 内核( ARMl76JZF-S),可广泛应用于移动电话和通用处理等领域。 (1)安装串口调试工具minicom 1.检测当前系统是否支持USB转串口 # Ismod I grep usbserial 2.安装 minicom # apt-get install minicom 3.配置minicom # minicom -s 4.测试minicom # minicom (2)使用E b o o t擦除N a n d F l a s h 1.用串口线或USB
[单片机]
S3C6410 时钟初始化
1. PHASE LOCKED LOOP(PLL) S3C6410里包含三个PLL(锁相环),APLL, MPLL, EPLL,通过设置它们将输入时钟同步输出达到操作CPU的工作频率的目的。如图1-1所示。 Voltage Controlled Oscillator (VCO)P 位来设置FIN进行分频。通过设置Main-Divider分频数,分频压控振荡器产生的输出时钟频率,分频之后的低频进入鉴相器ScalerS 位设置PLL的输出时钟频率都可以通过 PLL的时钟选择和输入参照时钟 图1-2描述了时钟产生逻辑。S3C6410有三个PLL锁相环,工作时钟也分为三组,APLL用来为ARM芯片提供工作时钟,MPLL为AXI,AHB
[单片机]
<font color='red'>S3C6410</font> <font color='red'>时钟</font><font color='red'>初始化</font>
s3c6410 pwm 学习
第一次自学直接看数据手册而不是大端的中文资料或者示例代码讲解。。不过这是大家必须要走过的过程。 开始吧! The 6410 RISC microprocessor comprises of five 32-bit timers. These timers are used to generate internal interrupts to the ARM subsystem. In addition, Timers 0 and 1 include a PWM function (Pulse Width Modulation), which can drive an external I/O signal. The PW
[单片机]
<font color='red'>s3c6410</font> pwm 学习
深入理解ARM体系架构(S3C6410)---PWM实例
S3C6410X中有5个定时器,这些定时器产生内部中断。其中,Timer0和Timer1具有PWM功能,而Timer2,3,4没有此功能。 The S3C6410X RISC microprocessorcomprises of five 32-bit timers. These timers are used to generate internal interruptsto the ARM subsystem. In addition, Timers 0 and 1 include a PWM function (PulseWidth Modulation),which can drive an external I/O si
[单片机]
深入理解ARM体系架构(<font color='red'>S3C6410</font>)---PWM实例
S3C6410核心初始化
一:异常向量表 异常定义:因为内部或者外部一些事件,导致处理器停下正在处理的工作,转而去处理这些发生的事件。当一种异常发生的时候,ARM处理器会跳转到对应该异常的固定地址去执行异常处理程序,而这个固定的地址,就称之为异常向量。以下为七个异常向量及处理函数跳转关系组成的表。 在Data Abort和IRQ之间有一段地址没有用上,在初始化的时候需要补上一段_not_used ,不然的话会报错,在发生异常的时候,程序会跳转到undefined_instruction: nop这段去执行,由于现在还不需要操作这些异常向量,所以在后面只加上nop。具体以后还会进一步学到 .text .global _start _st
[单片机]
<font color='red'>S3C6410</font>核心<font color='red'>初始化</font>
8.时钟初始化
ARM系统时钟初始化: 这就需要知道什么是时钟脉冲信号,什么是时钟频率,什么是时钟源。 时钟脉冲信号: 时钟脉冲信号:按一定的电压幅度,一定的时间间隔连续发出的脉冲信号。时钟脉冲信号是时序逻辑的基础,它用于决定逻辑单元中的状态何时更新。数字芯片中众多的晶体管都工作在开关状态,它们的导通和关断动作无不是按照时钟信号的节奏进行的 时钟脉冲图解: 1.2时钟脉冲频率: 时钟脉冲频率:就是在单位时间,如1秒,内产生的时钟脉冲个数。 1.3信号产生: 如何产生时钟信号:1.晶振2.锁相环PLL 1.3.1信号产生-晶振: 晶振全称晶体振荡器,是用石英晶体经精密切割磨削并镀上电极焊上引线做成。这种晶体
[单片机]
8.<font color='red'>时钟</font><font color='red'>初始化</font>
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved