在线问答
直播中

h1654155865.6393

9年用户 301经验值
擅长:可编程逻辑 测量仪表 嵌入式技术 模拟技术 处理器/DSP 控制/MCU
私信 关注

【OK210试用体验】裸机篇 -- 系统时钟配置

` 本帖最后由 q15920078530 于 2015-8-10 23:59 编辑

【OK210试用体验】裸机篇 -- 系统时钟配置

前面的一张帖提到了系统的时钟配置,我们没有主动去配置它,而是用了S5PV210在iROM启动阶段的BL0的系统时钟配置,其中PCLK=66MHz,而主要的ARMCLK的主频只有400MHz,我们知道,S5PV210主频可以达到1GHz,所以,现在要来学习一下如何配置到1G Hz。
      S5PV210的时钟系统可以参考官方详细的手册S5PV210_UM_REV1.1中的section 02_system CLOCK CONTROLLER

S5PV210的系统时钟

      S5PV210包含了三个时钟域,即主系统(MSYS)、显示系统(DSYS)、外设系统(PSYS)。 1.png

       在图中可以看到,各时钟系统域服务的对象情况:
          在主系统域中包含Cortex-A8处理器、DRAM内存控制器(DMC0和DMC1)、3D、SRAM(iROM、iRAM)、INTC、SPERI等;
          在显示系统域中包含了显示关联的模块,包括FIMC、FIMD、JPEG、多媒体IPs等;
          在外设系统域中包含了安全、IO外设、低功耗声音播放等。
       每个总线系统分别工作在200MHz(最大)、166MHz、133MHz。不同的域通过异步总线桥(BRG)相连接。
       S5PV210最顶层的时钟来源于:
8.png
2.png
       S5PV20包含4个PLL(锁相环),PLL就是用来将外设晶振(XXTI)的输入时钟的频率放大。
       S5PV210手册中官方建议使用24MHz的输入时钟作为APLL、MPLL、VPLL、EPLL的时钟源。 9.png
       这些时钟的在S5PV210的典型应用:
           - Cortex-A8和MSYS时钟域使用APLL(ARMCLK、HCLK_MSYS和PCLK_MSYS)
           - DSYS和PSYS时钟域(HCLK_DSYS、HCLK_PSYS、PCLK_DSYS和PCLK_PSYS)和外设时钟(GPIO、串口、SPI等)使用MPLL和EPLL
           - video clock使用VPLL
        时钟控制器允许为低速时钟绕过PLLs,也可以使用软件编程从每个时钟块连接和断开,达到降低功耗的目的。
       Mini210S外接的晶振频率(简称Fin)为24MHz,通过时钟控制逻辑PLL可以提高系统时钟。S5PV210共有4个倍频器,即PLL,包括APLL(供MSYS使用),MPLL(供DSYS使用),EPLL(供PSYS使用),VPLL(供video相关的时钟使用)

       S5PV210各时钟的关联: 3.png 7.png
       手册中推荐了时钟配置频率: 4.png
       PLL中各时钟驱动的系统域情况:
10.png

重要的系统时钟线路
     
在我们现在和之后对硬件进行驱动程序编写的时候,有这两张图非常重要,可以明确地看出系统时钟整条线路的配置。 5.png 6.png

程序编写与烧录
   
此调试程序需要用到上一帖中的所编写的串口通信程序,将所需要用到的时钟寄存器进行宏定义:
  1. #define APLL_LOCK                *((volatile u32 *)0xE0100000)
  2. #define MPLL_LOCK                *((volatile u32 *)0xE0100008)
  3. #define EPLL_LOCK                *((volatile u32 *)0xE0100010)
  4. #define VPLL_LOCK                *((volatile u32 *)0xE0100020)

  5. #define APLL_CON0                *((volatile u32 *)0xE0100100)
  6. #define MPLL_CON                *((volatile u32 *)0xE0100108)
  7. #define EPLL_CON0                *((volatile u32 *)0xE0100110)
  8. #define EPLL_CON1                *((volatile u32 *)0xE0100114)
  9. #define VPLL_CON                *((volatile u32 *)0xE0100120)

  10. #define CLK_SRC0                 *((volatile u32 *)0xE0100200)
  11. #define CLK_SRC1                 *((volatile u32 *)0xE0100204)
  12. #define CLK_SRC2                 *((volatile u32 *)0xE0100208)
  13. #define CLK_SRC3                 *((volatile u32 *)0xE010020C)
  14. #define CLK_SRC4                 *((volatile u32 *)0xE0100210)
  15. #define CLK_SRC5                 *((volatile u32 *)0xE0100214)
  16. #define CLK_SRC6                 *((volatile u32 *)0xE0100218)

  17. #define CLK_DIV0                *((volatile u32 *)0xE0100300)
  18. #define CLK_DIV1                *((volatile u32 *)0xE0100304)
  19. #define CLK_DIV2                *((volatile u32 *)0xE0100308)
  20. #define CLK_DIV3                *((volatile u32 *)0xE010030C)
  21. #define CLK_DIV4                *((volatile u32 *)0xE0100310)
  22. #define CLK_DIV5                *((volatile u32 *)0xE0100314)
  23. #define CLK_DIV6                *((volatile u32 *)0xE0100318)
  24. #define CLK_DIV7                *((volatile u32 *)0xE010031C)
     
配置系统时钟寄存器的步骤:

            1)设置系统PLL锁定时间
            2)配置PLL
            3)配置各模块分频系数
            4)切换到PLL时钟
     这时候系统时钟线路图的作用就大了,可以参考。
      时钟配置函数:
  1. void clock_init(void)
  2. {
  3.         /* 1. set PLL lock value */
  4.         APLL_LOCK = 0xFFFF;
  5.         MPLL_LOCK = 0xFFFF;
  6.         MPLL_LOCK = 0xFFFF;
  7.         VPLL_LOCK = 0xFFFF;

  8.         /* 2. set PLL PMS value */
  9.         /*                           P                     M                               S                    EN        */
  10.         APLL_CON0 = (3  << 8) | (125 << 16) | (1 << 0) | (1 << 31);        /* FOUT_APLL = 1000MHz */
  11.         MPLL_CON  = (12 << 8) | (667 << 16) | (1 << 0) | (1 << 31);        /* FOUT_MPLL = 667MHz */
  12.         EPLL_CON0 = (3  << 8) | (48  << 16) | (2 << 0) | (1 << 31);        /* FOUT_EPLL = 96MHz */
  13.         VPLL_CON  = (6  << 8) | (108 << 16) | (3 << 0) | (1 << 31);        /* FOUT_VPLL = 54MHz */

  14.         /* 3. wiat PLL LOCK */
  15.         while (!(APLL_CON0 & (1 << 29)));
  16.         while (!(MPLL_CON  & (1 << 29)));
  17.         while (!(EPLL_CON0 & (1 << 29)));
  18.         while (!(VPLL_CON  & (1 << 29)));

  19.         CLK_SRC0 = 0x10001111;

  20.         CLK_DIV0 =         (0 << 0)  |        /* APLL_RATIO = 0, freq(ARMCLK) = MOUT_MSYS / (APLL_RATIO + 1) = 1000MHz */
  21.                                    (4 << 4)  |        /* A2M_RATIO = 4, freq(A2M) = SCLKAPLL / (A2M_RATIO + 1) = 200MHz */
  22.                                 (4 << 8)  |        /* HCLK_MSYS_RATIO = 4, freq(HCLK_MSYS) = ARMCLK / (HCLK_MSYS_RATIO + 1) = 200MHz */
  23.                                 (1 << 12) |        /* PCLK_MSYS_RATIO = 1, freq(PCLK_MSYS) = HCLK_MSYS / (PCLK_MSYS_RATIO + 1) = 100MHz */
  24.                                 (3 << 16) | /* HCLK_DSYS_RATIO = 3, freq(HCLK_DSYS) = MOUT_DSYS / (HCLK_DSYS_RATIO + 1) = 166MHz */
  25.                                 (1 << 20) | /* PCLK_DSYS_RATIO = 1, freq(PCLK_DSYS) = HCLK_DSYS / (PCLK_DSYS_RATIO + 1) = 83MHz */
  26.                                 (4 << 24) |        /* HCLK_PSYS_RATIO = 4, freq(HCLK_PSYS) = MOUT_PSYS / (HCLK_PSYS_RATIO + 1) = 133MHz */
  27.                                 (1 << 28);        /* PCLK_PSYS_RATIO = 1, freq(PCLK_PSYS) = HCLK_PSYS / (PCLK_PSYS_RATIO + 1) = 66MHz */
  28.                
  29. }

      控制变量,应用软件延时:
  1. void delay(unsigned long count)
  2. {
  3.                 volatile unsigned long i = count;
  4.                        
  5.                 while (i--);
  6. }



实验现象

       程序中实现流水灯,配置不同的系统时钟,采用相同的延时函数,可以看到流水灯交替闪烁速度的差别。 11.png 12.png

` 13.png

更多回帖

发帖
×
20
完善资料,
赚取积分