热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

时钟分频原理

产生了400MHz的FCLK时钟;需要设置时钟分频;一个12MHz的时钟经过锁相环以后;注意这个时候的FCLK频率就是晶振提供的频率;0~15位是设

时钟分频原理 - 时钟分频原理详解

 

 

时钟分频原理

  如果cpu是计算机的大脑,电流是计算机的血液,那么时钟则是计算机的心脏,时钟频率决定了处理器运算的快慢,它的每一次“跳动”都驱动着处理器不停的执行命令。不同的是,人的各个部位心率是一样的,但计算机却有多个频率,而且每个部位可能有不同的频率,比如“大脑”有一个频率,“手“有一个频率,“脚”使用的是另外一个频率,这样就产生了两个问题:怎么产生这些不同的频率?处理器怎么与自己不同频率的外设实现交互?

 

  怎么产生这些不同的频率?

  为了获取稳定的时钟,我们一般使用外部晶振来提供,晶振是由石英和震荡电路组成的,石英能够提供稳定的频率。一般一个计算机系统最少需要一个晶振,有些特殊的外设也会有自己特有的晶振,比如网卡,显卡等,但是对于大多数连接cup的外设来说是没有自己的晶振的,那么就需要cpu给他们提供时钟,然而不同的外设需要的时钟不一样,cpu是怎么给这些外设提供不同的时钟呢?

  ARM处理器主要给外设提供了两种连接总线,AHB总线(Advanced high Performance Bus)和APB总线,这两种总线的时钟在没有初始化之前是一样的,频率等于外部晶振提供的频率,在初始化以后,它们就可以为外设提供不同的时钟了。

  AHP和APB总线的内容将放到后面章节作为补充知识了解,因为他们对我们分析uboot的启动过程关系不大。由于这两种总线初始化以后,时钟是不一样的,所以连接的外设也不一样,如下图,一些工作频率较高的外设挂接在AHB总线上,比如内存,nandflash,LCD控制器等,而工作频率比较低的外设则挂接在APB总线上,比如UART串口,Watchdog,GPIO,USB等(注意:这里使用挂接,是因为这些设备是可以拔除的,而不影响其他外设的工作)。

  

  我们这里先不管这些外设是怎么和总线连接的,但是先了解一点:连接在同一个总线上的外设,获取到的时钟是一样的。当AHB和APB上的时钟都不能满足外设需求的时候,就需要PWM TImer来帮忙了。

  

  上面这张图是s3c2440的时钟生成图,看上去挺复杂的,其实并不是那么回事,对于uboot的启动来说,只要了解图中红色框框的部分就可以了,但是如果要编写UBS驱动或者摄像头驱动,则会涉及到图中灰绿色的部分。因为我们只要分析uboot启动过程中涉及到的东西,所以对USB和cam部分就不细讲了。

  图中红色框表示的是主时钟的产生过程,灰绿色的框表示USB时钟的产生过程,红色线条表示输出HCLK,绿色线条表示PCLK,黄色线条表示FCLK。

  uboot启动的时候,需要设置时钟分频,分频的目的就是产生三种时钟:PCLK、FCLK和HCLK,PCLK供APB总线使用,HCLK供AHB总线使用,FCLK则供cpu使用,而且从datasheet的电气参数那一章可以查到FCLK,HCLK和PCLK的最大值分别是400MHz,100MHz和50MHz。下面就依照图中的步骤来分析,这三种时钟是怎么产生的。下图是对上面这张图的简概:

  

  1.时钟源

  为了减少外界环境对开发板的电磁干扰,降低制作成本,通常开发板的外部晶振时钟频率都是很低的。从图中第一个红框可以看出,cpu可以连接两种外部时钟源,一种是振荡时钟源,一种是时钟信号,前者就是石英晶体振荡电路,后者是其他振荡器产生的时钟信号,比如信号发生器产生的时钟信号,虽然两者都是特定频率的正弦波形,但是在cpu的接线方式上是有不同的。

  \

  从这张表中可以看出,s3c2440可以连接两个时钟源,一个是主时钟源,一个是USB时钟源,如果主时钟源需要接晶振源,则OM3需要为0,也就是要接地(这里暂时不讨论ubs时钟),同理,如果UBS时钟源需要接晶振源,则OM2要接地。从电路图中可以看到,OM2和OM3都接地,而且XTIpll引脚和XTOpll引脚接的是外部12M晶振,所以这里开发板的时钟源是12M的外部晶振。(USB的时钟源这里不讨论)

  

  需要注意的是,晶振提供的时钟,只有在上电以后才开始起振的,而外部提供的信号时钟是板子没有上电的时候就已经在振荡了,所以对晶振时钟源需要作一个特殊的处理——变频锁定。

  2.变频锁定

  开发板刚上电的时候,晶振OSC开始提供晶振时钟,由于系统刚刚上电,电压信号等都还不稳定,这时复位信号(nRESET)拉低,那么外部晶振则直接作为系统时钟FCLK,这时的FCLK是不规则的,为了让cpu使用规则的时钟频率,需要将clock disable一小段时间,这个时间就是图中的Lock Time,在这段时间里面,电压会慢慢稳定,时钟频率也会调整到一个新的稳定状态(VCO is adapted to new clock frequency),而且这段时间里面,FCLK是为0的,也就是说cpu是不会运行的,当这个Lock Time结束以后,FCLK就会获得一个新的频率(FCLK is new frequency)。注意这个时候的FCLK频率就是晶振提供的频率,他们的大小是一样的,当经过倍频以后,这个值将数倍的变化。

  

  下面是变频锁定时间的设定寄存器:0~15位是设置主时钟源锁定时间的,后15位是设置USB锁频时间的,这里不考虑,值得注意的是对应的锁频时间可以从datasheet的电气数据表中查到(PLL Lock Time)。

  

  3.倍频设置(锁相环)

  当cpu能够获取到稳定的时钟时,就需要对时钟进行倍频了,现在知道外部晶振输入的时钟时12M,那怎样把这个时钟提高到100MHz,甚至是400MHz呢?这就涉及到了时钟生成图的第二个红框框了(注意框框上面的S,P,M字样),这个叫锁相环(PLL),主频的倍频操作是由MPLL来设置的,而USB的倍频操作是由UPLL来设置的,UPLL暂时不讨论。所以要让外部时钟经过变化,扩大到400M,就需要对MPLLCON寄存器进行设置。

  

  从上图可以看出,不管是MLLCON或者UPLLCON,都由三个部分组成,主分频、预分频、后分频控制位,这些分频数值决定了12M进去的频率,将会输出多大频率,下面这张表是手册的推荐设置:比如我们要将12M是时钟频率倍频成405M,则需要MDIV=0x7f,PDIV=0x2,SDIV=1,注意49M和96M是给USB的UPPLCON设置的。

  

  当然也可以不参考这个表格,使用计算公式

  

  4.设置比例(分频器)

  设置完PLL寄存器以后,当稳定的时钟通过锁相环则会输出更大倍数的频率,而这个更大倍数的频率则是FCLK,现在这个值则是400MHz,而不是12MHz了,现在我们得到了想要的FCLK,那怎么得到PCLK和HCLK呢?下面就涉及到分频器的设置。

  

  怎么设置HDIVN和PCIVN的数值,主要查找下面的表:

  

  比如我们要将HCLK设置为100,PCLK设置为50, 那么HCLK=FCLK/4,PCLK=FCLK/8,查表可知为1:4:8,所以HDIVN=0x2,PDIVN=0x1, dvin_UPLL是UBS的时钟,这里不讨论。

  但是根据datasheet说明,当HDIV设置为非0的时候,cpu总线模式要进行改变,默认情况下FCLK=HCLK,cpu工作在fast bus mode快速总线模式下,HDIV设置为非0后,FCLK和HCLK不再相等,要将cpu改为异步总线模式,需要使用对应的代码进行设置。

  

  所以上面三步的代码可总结如下:

  [plain] view plain copy#define S3C2410_MPLL_200MHZ ((0x5c《《12)|(0x04《《4)|(0x00))

  #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)

  * S3C2410: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)

  * 其中: m = MDIV + 8, p = PDIV + 2, s = SDIV

  * 对于本开发板,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” /* 写入控制寄存器 */

  );

  /* 判断是S3C2410还是S3C2440 */

  if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))

  {

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

  }

  else

  {

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

  }

  }

  对于USB和CAM的时钟设置都是相似的,这里就不累述了

  补充:

  前面介绍了锁相环寄存器的设置,这里对锁相环的工作原理作一个简述。一个12MHz的时钟经过锁相环以后,产生了400MHz的FCLK时钟,它是怎么办到的呢?

  锁相环的作用比较多,不仅可以倍频,还可以合成频率,音频解码等,实现原理有所不同,下图是S3c2440的锁相环实现原理图:

  

  (1)当外部时钟Fin进入锁相环的时候,预分频器(Divider P)会将该时钟进行处理得到Fref信号,这个信号是reference参考信号,用于后面分频的相位参考。

  (2)Fref将第一次进入PFD(Phase Frequency Detector)相位鉴定器,它主要完成Fref和Fvco的相位鉴定,当输出和输入信号的频率和相位保持恒定不变的时候,锁相环进入相位锁定的状态,当输出和输入信号的频率和相位有差异的时候,则会发送信号给PUMP。

  (3)PUMP会将PFD的控制信号转换成合适电压信号给循环滤波器

  (4)滤波器会对从PUMP过来的波形进行过滤,然后将信号送给VCO

  (5)VCO(Voltage Controlled Oscillator),压控振荡器,这里是倍频的关键步骤,压控振荡器的振荡频率会随时间而变,锁相环进入“频率牵引”,自动跟踪捕捉输入信号的频率,然后将输出进行主分频(Divider M),产生Fvco.

  (6)Fvco会进入PFD与Fref进行相位和频率的差异对比,如果处在差异,则继续进入循环,如果没有差异,则PFD停止向PUMP发送信号,锁相环进入相位锁定的状态。

  (7)当锁相环进入相位锁定的状态,VCO的输出将通过后分频器(Divider S)输出MPLL或者UPLL。

  所以要使用锁相环,就需要设置XPLLCON的P,M,S;关于锁相环的更具体的原理,请GOOGLE。

  至于分频器的工作原理比较简单,主要是改变波形的占空比达到将高频变低频的效果,所以需要设置HDIVN和PDIVN。

  总结:这篇文章分析了怎么设置时钟分频,让cpu以及外部设备工作在更高的频率上面,主要涉及三个寄存器的设置——LOCKTIMRE,MPLLCON,CLOCKDIVN

  再回忆一下开发板启动的过程,当开发板上电的时候,启动过程是:进入管理模式——关看门狗——关中断——时钟分频。。.

  在设置时钟分频以前,cpu都是工作在12Mhz频率的,当设置完时钟分频后,cpu的工作频率将是400MHZ,这相当于完成了一个蜕变,从一个普通人变成了超人,多了几十倍的反应速度,更加高效的执行后面的代码。想想如果没有对时钟进行倍频处理,仍然让它运行在12MHz,处理同一件任务多要30多倍的时间,将是一件多么折磨人的事情。

  接下来将会继续对时钟这个问题进行分析,虽然这里分析了怎么设置时钟分频,但是这只是开始,后面将对省电模式,快启动,慢启动,实时时钟,pwm时钟等内容进行讲解。


推荐阅读
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • Windows7企业版怎样存储安全新功能详解
    本文介绍了电脑公司发布的GHOST WIN7 SP1 X64 通用特别版 V2019.12,软件大小为5.71 GB,支持简体中文,属于国产软件,免费使用。文章还提到了用户评分和软件分类为Win7系统,运行环境为Windows。同时,文章还介绍了平台检测结果,无插件,通过了360、腾讯、金山和瑞星的检测。此外,文章还提到了本地下载文件大小为5.71 GB,需要先下载高速下载器才能进行高速下载。最后,文章详细解释了Windows7企业版的存储安全新功能。 ... [详细]
  • 本文介绍了如何使用MATLAB调用摄像头进行人脸检测和识别。首先需要安装扩展工具,并下载安装OS Generic Video Interface。然后使用MATLAB的机器视觉工具箱中的VJ算法进行人脸检测,可以直接调用CascadeObjectDetector函数进行检测。同时还介绍了如何调用摄像头进行人脸识别,并对每一帧图像进行识别。最后,给出了一些相关的参考资料和实例。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • RouterOS 5.16软路由安装图解教程
    本文介绍了如何安装RouterOS 5.16软路由系统,包括系统要求、安装步骤和登录方式。同时提供了详细的图解教程,方便读者进行操作。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
author-avatar
小周颖子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有