好了,贴源码!

//common.h

[cpp] view plaincopy
  1. #ifndef COMMON_H
  2. #define COMMON_H
  3. typedef unsigned long uint32;
  4. #define MASK_CODE(LSB_LOCATION,FIELD_LEN)                   ((((uint32)1<<FIELD_LEN)-1)<<LSB_LOCATION)
  5. #define FILL_BITS(MEM_ADDR,LSB_LOCATION,FIELD_LEN,VALUE)    (*(volatile uint32 *)(MEM_ADDR)) = ( (*(volatile uint32 *)(MEM_ADDR)) & ~MASK_CODE((LSB_LOCATION),(FIELD_LEN)) ) | ( ((uint32)(VALUE)<<(LSB_LOCATION)) & MASK_CODE((LSB_LOCATION),(FIELD_LEN)) )
  6. //注:FILL_BITS(MEM_ADDR,LSB_LOCATION,FIELD_LEN,VALUE)这个宏,它执行的操作是,
  7. //用VALUE这个数填充MEM_ADDR地址处从第LSB_LOCATION位开始的FIELD_LEN个位.
  8. #define SET_REG(REG_ADDR,LSB_LOCATION,FIELD_LEN,VALUE)          FILL_BITS(REG_ADDR,LSB_LOCATION,FIELD_LEN,VALUE)
  9. #endif

//clock.h

[cpp] view plaincopy
  1. #ifndef CLOCK_H
  2. #define CLOCK_H
  3. #include"common.h"
  4. #define CONFIG_SYS_CLK_FREQ 12000000
  5. void set_sys_clk(uint32 mode);
  6. uint32 get_ARMCLK(void);
  7. uint32 get_FCLK(void);  //即APLL
  8. uint32 get_HCLK(void);
  9. uint32 get_PCLK(void);
  10. void change_freq(uint32 arm_ratio,uint32 hclkx2_ratio,uint32 hclk_ratio,uint32 pclk_ratio);
  11. //  0-15        0-7                0-1          0-15
  12. //这四个参数加1后才是实际分频。
  13. #define rAPLL_LOCK      (*(volatile uint32 *)(0x7e00f000))
  14. #define rMPLL_LOCK      (*(volatile uint32 *)(0x7e00f004))
  15. #define rEPLL_LOCK      (*(volatile uint32 *)(0x7e00f008))
  16. #define rAPLL_CON   (*(volatile uint32 *)(0x7E00F00C))
  17. #define rMPLL_CON   (*(volatile uint32 *)(0x7E00F010))
  18. #define rEPLL_CON0  (*(volatile uint32 *)(0x7E00F014))
  19. #define rEPLL_CON1  (*(volatile uint32 *)(0x7E00F018))
  20. #define rCLK_SRC    (*(volatile uint32 *)(0x7E00F01C))
  21. #define rOTHERS         (*(volatile uint32 *)(0x7E00F900))
  22. #define rMISC_CON   (*(volatile uint32 *)(0x7E00F838))
  23. #define rCLK_DIV0   (*(volatile uint32 *)(0x7E00F020))
  24. //--------
  25. #define _APLL_MDIV  1000        //reset: 0x190  ,10bits
  26. #define _APLL_PDIV  10      //reset: 0x3    ,6bits
  27. #define _APLL_SDIV  1       //reset: 0x2    ,3bits
  28. #define _MPLL_MDIV  1000        //reset: 0x214  ,10bits
  29. #define _MPLL_PDIV  10      //reset: 0x6    ,6bits
  30. #define _MPLL_SDIV  1       //reset: 0x3    ,3bits
  31. #define _ARM_RATIO  2       //0-15
  32. #define _HCLKX2_RATIO   3       //0-7
  33. #define _HCLK_RATIO 0       //0-1
  34. #define _PCLK_RATIO 3       //0-15
  35. /*
  36. PLL_FOUT:
  37. FOUT = MDIV X FIN / (PDIV X 2^SDIV)
  38. MDIV: 64 ≤ MDIV ≤ 1023
  39. PDIV: 1 ≤ PDIV ≤ 63
  40. SDIV: 0 ≤ SDIV ≤ 5
  41. FVCO (=MDIV X FIN / PDIV): 800MHz ≤ FVCO ≤ 1600MHz
  42. FOUT: 40MHz ≤ FVCO ≤ 1600MHz
  43. FIN : 10MHz ≤ FIN ≤ 20MHz
  44. Don't set the value P and M to all zeros.
  45. CLK:
  46. ARM_CLK     =   APLLOUT / (_ARM_RATIO+1)
  47. HCLKX2      =   MPLLOUT / (_HCLKX2_RATIO+1)
  48. HCLK        =   HCLKX2  / (_HCLK_RATIO+1)
  49. PCLK        =   HCLKX2  / (_PCLK_RATIO+1)
  50. 设置时还需注意HCLK必须是PCLK的整偶倍数
  51. */
  52. #endif

需要修改频率时,只需修改clock.h文件中的下列宏的值即可:

[cpp] view plaincopy
  1. //--------
  2. #define _APLL_MDIV  1000        //reset: 0x190  ,10bits
  3. #define _APLL_PDIV  10      //reset: 0x3    ,6bits
  4. #define _APLL_SDIV  1       //reset: 0x2    ,3bits
  5. #define _MPLL_MDIV  1000        //reset: 0x214  ,10bits
  6. #define _MPLL_PDIV  10      //reset: 0x6    ,6bits
  7. #define _MPLL_SDIV  1       //reset: 0x3    ,3bits
  8. #define _ARM_RATIO  2       //0-15
  9. #define _HCLKX2_RATIO   3       //0-7
  10. #define _HCLK_RATIO 0       //0-1
  11. #define _PCLK_RATIO 3       //0-15

//clock.c

[cpp] view plaincopy
  1. #include"clock.h"
  2. //注:FILL_BITS(MEM_ADDR,LSB_LOCATION,FIELD_LEN,VALUE)这个宏,它执行的操作是,
  3. //用VALUE这个数填充MEM_ADDR地址处从第LSB_LOCATION位开始的FIELD_LEN个位.
  4. void set_sys_clk(uint32 mode)
  5. {                                   //mode:     0:asyn mode 异步模式
  6. //      other:syn  mode 同步模式
  7. //两种模式的区别参考3-3页的Figure 3.2
  8. uint32 *p;
  9. uint32 temp;
  10. rAPLL_LOCK = 0xffff;
  11. rMPLL_LOCK = 0xffff;
  12. rMISC_CON &= ~(1u<<19);                        //SYNC667  0 : Normal Moe, 1 : Sync 667MHz Mode。       这里选用Normal mode
  13. if(mode==0)
  14. {
  15. //设置同步模式为异步
  16. rOTHERS &= ~0x80;                              //异步模式
  17. while((rOTHERS & 0xf00) != 0);                  //等待OTHERS的8~11位为0
  18. rOTHERS &= ~0x40;
  19. }
  20. else
  21. {
  22. //设置为同步模式。
  23. rOTHERS |= 0x40;                              //同步模式
  24. __asm{
  25. nop;
  26. nop;
  27. nop;
  28. nop;
  29. nop;
  30. }
  31. rOTHERS |= 0x80;
  32. while((rOTHERS & 0xf00) != 0xf00);             //等待OTHERS的8~11位为1111
  33. }
  34. //设置ARMCLK,HCLKX2,HCLK和PCLK
  35. temp=rCLK_DIV0;
  36. p=&temp;
  37. FILL_BITS(p,0,4,_ARM_RATIO);
  38. FILL_BITS(p,9,3,_HCLKX2_RATIO);
  39. FILL_BITS(p,8,1,_HCLK_RATIO);
  40. FILL_BITS(p,12,4,_PCLK_RATIO);
  41. rCLK_DIV0=temp;
  42. //设置APLL,得到APLLOUT
  43. temp=rAPLL_CON;
  44. p=&temp;
  45. FILL_BITS(p,16,10,_APLL_MDIV);
  46. FILL_BITS(p,8,6,_APLL_PDIV);
  47. FILL_BITS(p,0,3,_APLL_SDIV);
  48. temp |= (1u<<31);
  49. rAPLL_CON=temp;
  50. //设置MPLL,得到MPLLOUT
  51. temp=rMPLL_CON;
  52. p=&temp;
  53. FILL_BITS(p,16,10,_MPLL_MDIV);
  54. FILL_BITS(p,8,6,_MPLL_PDIV);
  55. FILL_BITS(p,0,3,_MPLL_SDIV);
  56. temp |= (1u<<31);
  57. rMPLL_CON=temp;
  58. //选择源
  59. temp=rCLK_SRC;
  60. p=&temp;
  61. FILL_BITS(p,0,1,1);     //选择APLLOUT
  62. FILL_BITS(p,1,1,1);     //选择MPLLOUT
  63. rCLK_SRC=temp;
  64. }
  65. void change_freq(uint32 arm_ratio,uint32 hclkx2_ratio,uint32 hclk_ratio,uint32 pclk_ratio)
  66. {       //  0-15        0-7     0-1     0-15
  67. uint32 *p;
  68. uint32 temp;
  69. temp=rCLK_DIV0;
  70. p=&temp;
  71. FILL_BITS(p,0,4,arm_ratio);
  72. FILL_BITS(p,9,3,hclkx2_ratio);
  73. FILL_BITS(p,8,1,hclk_ratio);
  74. FILL_BITS(p,12,4,pclk_ratio);
  75. rCLK_DIV0=temp;
  76. }
  77. #define APLL 1
  78. #define MPLL 2
  79. #define EPLL 3
  80. static uint32 get_PLLCLK(int pllreg)    //返回0说明异常
  81. {
  82. uint32 r, m, p, s;
  83. if (pllreg == APLL)
  84. r = rAPLL_CON;
  85. else if (pllreg == MPLL)
  86. r = rMPLL_CON;
  87. else if (pllreg == EPLL)
  88. r = rEPLL_CON0;
  89. else
  90. return 0;
  91. m = (r>>16) & 0x3ff;
  92. p = (r>>8) & 0x3f;
  93. s = r & 0x7;
  94. return (m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s))));
  95. }
  96. /* return ARMCORE frequency */
  97. uint32 get_ARMCLK(void)
  98. {
  99. uint32 div;
  100. div = rCLK_DIV0;
  101. return (get_PLLCLK(APLL) / ((div & 0x7) + 1));
  102. }
  103. /* return FCLK frequency */
  104. uint32 get_FCLK(void)
  105. {
  106. return (get_PLLCLK(APLL));
  107. }
  108. /* return HCLK frequency */
  109. uint32 get_HCLK(void)
  110. {
  111. uint32 fclk;
  112. uint32 hclkx2_div = ((rCLK_DIV0>>9) & 0x7) + 1;
  113. uint32 hclk_div = ((rCLK_DIV0>>8) & 0x1) + 1;
  114. if(rOTHERS & 0x80)
  115. fclk = get_FCLK();      // SYNC Mode
  116. else
  117. fclk = get_PLLCLK(MPLL);    // ASYNC Mode
  118. return fclk/(hclk_div * hclkx2_div);
  119. }
  120. /* return PCLK frequency */
  121. uint32 get_PCLK(void)
  122. {
  123. uint32 fclk;
  124. uint32 hclkx2_div = ((rCLK_DIV0>>9) & 0x7) + 1;
  125. uint32 pre_div = ((rCLK_DIV0>>12) & 0xf) + 1;
  126. if(rOTHERS & 0x80)
  127. fclk = get_FCLK();      // SYNC Mode
  128. else
  129. fclk = get_PLLCLK(MPLL);    // ASYNC Mode
  130. return fclk/(hclkx2_div * pre_div);
  131. }

set_sys_clk(uint32 mode)函数既设置锁相环又根据已定义好的宏设置ARMCLK和HCLK等的分频。mode为0时为异步模式,为1时为同步模式。初始化时一般用这个函数。

change_freq(uint32,uint32,uint32,uint32)根据输入的参数设置ARMCLK和HCLK等的分频,但不改变PLL的设置。通过这个函数可以快捷的实现动态变频。

其他的get*****()函数就请读者自己看吧。

6410的系统时钟设置(下)---几个常用函数的C源码相关推荐

  1. 6410的系统时钟设置(中)---相关寄存器介绍

    上篇中已经详细分析了6410时钟系统的结构,现在就介绍下几个与时钟设置相关的寄存器. 1.APLL_LOCK.MPLL_LOCK.EPLL_LOCK 这三个寄存器的低十六位分别表示APLL.MPLL. ...

  2. 6410的系统时钟设置(上)---6410时钟控制逻辑框架分析

    本文主要介绍6410内核和AHB.APB总线的时钟设置. 6410的时钟逻辑结构还是比较清晰的,配置起来并不难(曾让笔者极度抓狂的是Freescale Kinetis系列的片子,系统时钟配置起来很麻烦 ...

  3. STM32系统时钟设置(标准库)

    1.STM32F407时钟树 2.系统时钟相关的结构 HSE高速外部时钟信号 锁相环PLL 锁相环的主要作用就是对时钟进行倍频,然后把时钟输出到各个功能部件.PLL有两个,一个主PLL,另一个是专用的 ...

  4. STM32系统时钟设置,采用外部有源晶振相关配置问题

    今天在调试STM32系统时钟设置时遇到一个问题:TIM2定时1Ms,TIM2中断服务函数time++,time=100时LED状态改变.程序运行后发现LED不是按照0.1S的时间闪烁,闪烁的很慢. 查 ...

  5. 基于Java毕业设计疫情下的进出口食品安全信息管理系统源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计疫情下的进出口食品安全信息管理系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计疫情下的进出口食品安全信息管理系统源码+系统+mysql+lw文档+部署软件 本源 ...

  6. java计算机毕业设计微服务”架构下新闻头条的设计与实现源码+系统+数据库+lw文档

    java计算机毕业设计微服务"架构下新闻头条的设计与实现源码+系统+数据库+lw文档 java计算机毕业设计微服务"架构下新闻头条的设计与实现源码+系统+数据库+lw文档 本源码技 ...

  7. Linux系统常用函数,浅谈linux下的一些常用函数的总结(必看篇)

    1.exit()函数 exit(int n)  其实就是直接退出程序, 因为默认的标准程序入口为int main(int argc, char** argv),返回值是int型的. 一般在shell下 ...

  8. android ctrl 左键鼠标左键直接打开xml文件夹,设置Android Studio通过Ctrl+左键查看源码...

    开始学习android的时候希望能点进系统提供的控件中查看源码,但是实际操作发现,看到的每个源文件方法都是抛出的Exception,所以想要设置成可以直接查看具体实现,记录下我自己的操作方法. 1.首 ...

  9. 我在windows10下,使用CMake gui 编译krita源码,CMake gui报错:LibMyPaint_DIR-NOTFOUND

    系列文章目录 文章目录 系列文章目录 前言 一.原因 二.解决 1.引入库 前言 我在windows10下,使用CMake gui 编译krita源码 where is the source code ...

最新文章

  1. 用tcpdump查看端口包
  2. 史上首次,强化学习算法控制核聚变登上Nature:DeepMind让人造太阳向前一大步...
  3. 50 种系统免遭黑客侵袭的方法 [2017 年版]
  4. 在线人员统计系统php,PHP统计当前在线人数 - 案例源码
  5. JZOJ 5257. 小X的佛光
  6. java 定义一组常量用什么最好_Java语言中定义常量注意事项解析
  7. 又跌!6月全国程序员工资新统计,太扎心
  8. python开发自动化创建一个任务下发到手机_如何利用Fabric自动化你的任务
  9. 技术分享|前端性能 关键性能指标以及测量工具介绍
  10. MyBatis之输入与输出(resultType、resultMap)映射
  11. 编译安装时的--prefix参数的使用方法,很实用,mark一下
  12. 开源包管理器Homebrew被曝 RCE,影响 macOS 和 Linux 系统
  13. zip、rar文件格式
  14. journalctl用法详解
  15. 最短路算法模板(Dijkstra、Bellman_ford、spfa、Floyd)
  16. 打蚊子表情包_打死蚊子表情包 - 打死蚊子微信表情包 - 打死蚊子QQ表情包 - 发表情 fabiaoqing.com...
  17. ⭐❤️sqlite数据库使用大全❤️⭐
  18. 【打卡算法】 26、删除有序数组中的重复项 算法解析
  19. LINQ分页和排序,skip和Take 用法
  20. oppo小布机器人_OPPO小布助手2.0强势来袭 三大版块迎来重大升级

热门文章

  1. 预测数据时数据类型是object导致报错TypeError: unsupported operand type(s) for -: ‘str‘ and ‘float‘
  2. Nginx 502报错(django+nginx,而非php-fmp)
  3. 利用计算机语言进行并行性描述,有没有一种语言可以利用大规模并行计算机?...
  4. Lua虚拟机中的数据结构与栈
  5. PyCharm Active Code Generator
  6. $.each()和$().each(),以及forEach()的用法
  7. (转载) Android两个子线程之间通信
  8. 新浪sae平台进行数据库的连接
  9. BGP双线的真真假假
  10. Log4J 1.x 配置详解