Systemlnit时钟系统初始化函数详解

时钟系统知识总结:

1.STM32有5个时钟源 HSI、HSE、LSI、LSE、PLL.

HSI是高速内部时钟,RC振荡器,频率为8MHZ,精度不高。

HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHZ至16MHZ。

LSI是低速内部时钟,RC振荡器,频率为40KHZ,提供低功耗时钟。WDG

LSE是低速外部时钟,接频率为32.768KHZ的石英晶体。RTC

PLL为锁相环倍频输出,其时钟输入源可选为HSI/2、HSE或HSE/2。倍频可选择为2至16倍,但是其输出频率最大不得超过72MHZ。

2.系统时钟SYSCLK可来源于三个时钟源:

HSI振荡器时钟、HSE振荡器时钟、PLL时钟

3.STM32可以选择一个时钟信号输出到MCO脚上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。

4.任何一个外设在使用之前,必须首先使能其相应的时钟。

RCC相关配置寄存器

typedef struct
{
__IO uint32_t CR;           //HSI HSE CSS PLL 等的使能和就绪标志位
__IO uint32_t CFGR;     //PLL等的时钟选择,分频系数设定
__IO uint32_t CIR;          //清除/使能就绪中断
__IO uint32_t APB2RSTR; //APB2线上外设复位寄存器
__IO uint32_t APB1RSTR; //APB1线上外设复位寄存器
__IO uint32_t AHBENR;       //DMA,SIO等时钟时钟
__IO uint32_t APB2ENR;      //APB2线上外设时钟使能
__IO uint32_t APB1ENR;      //APB1线上外设时钟时钟使能
__IO uint32_t BDCR;     //备份域寄存器
__IO uint32_t CSR;          //控制状态寄存器
} RCC_TypeDef;

SystemInit源码解析:

 RCC->CR |= (uint32_t)0x00000001; //启用内部8MHZ振荡器

因为芯片容量不同所以初始化的时候也不同,把上图画框的初始化图上红框图。

RCC->CFGR &= (uint32_t)0xF8FF0000;

RCC->CR &= (uint32_t)0xFEF6FFFF;//把红框的设为0

  RCC->CR &= (uint32_t)0xFFFBFFFF;//把红框的设为0

 RCC->CFGR &= (uint32_t)0xFF80FFFF;把红框的设为0

RCC->CIR = 0x009F0000;//把所有的中断关掉

以上是设置成默认的状态,相关的一些不打开。

在调用的是SetSysClock()时钟设置函数。

以设置72MHz为例:

#define  RCC_CR_HSEON  ((uint32_t)0x00010000)//第16位
RCC->CR |= ((uint32_t)RCC_CR_HSEON);//打开外部高数时钟

等待时钟稳定
#define  RCC_CR_HSERDY        ((uint32_t)0x00020000)
#define HSE_STARTUP_TIMEOUT   ((uint16_t)0x0500) do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

首先会检查一下就绪没有,如果没有就绪继续执行do{}while里面的程序,直到执行500次还是没有就绪就跳出循环

 if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  

从循环跳出后检查是就绪了正常跳出循环还是超时跳出循环,此段代码记录一个状态,如果是就绪正常跳出会执行以下代码,如果是异常跳出循环的就什么都不做。

#define  FLASH_ACR_PRFTBE                  ((uint8_t)0x10)
#define  FLASH_ACR_LATENCY                 ((uint8_t)0x03)
#define  FLASH_ACR_LATENCY_2               ((uint8_t)0x02)FLASH->ACR |= FLASH_ACR_PRFTBE; //预取缓冲区开启。FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); //时延设置为0等待状态
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;  //设置成2个等待状态

上面这3行代码是因为CPU的速度比Flash的速度快很多倍,所以在操作之前先去等待几个时钟周期。为什么先设置0等待状态在设置2个等待状态,可以理解为先初始化再设置为自己想要的。

RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; //AHB不分频,从而达到HCLK72MHZ的目的

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/*因为AHB被设置1号成不分频,
所以2号可以是72MHZ,要想3号也是72MHZ就必须设置APB2为不分频。*/

#define  RCC_CFGR_PPRE1_DIV2                 ((uint32_t)0x00000400)
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;//1好号是72MHZ,要想2是36MHZ就APB1就必须2分频。

因为不是STM32F10X_CL所以执行的是else里面的代码如下由于太多了就不详讲:

#define  RCC_CFGR_PLLSRC                    ((uint32_t)0x00010000)
#define  RCC_CFGR_PLLXTPRE                  ((uint32_t)0x00020000)
#define  RCC_CFGR_PLLMULL                  ((uint32_t)0x003C0000)
#define  RCC_CFGR_PLLSRC_HSE                ((uint32_t)0x00010000)
#define  RCC_CFGR_PLLMULL9                  ((uint32_t)0x001C0000)RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);

8MHZ通过1号选择器到2号选择器到3号倍频器(8*9=72MHZ),4号选择器选择72MHZ到5号AHB(1分频),6号72MHZ,7号APB1(2分频)36MHZ,8号APB2(1分频)72MHZ。

#define  RCC_CR_PLLON                        ((uint32_t)0x01000000)
RCC->CR |= RCC_CR_PLLON;//使能PLL

#define  RCC_CR_PLLRDY   ((uint32_t)0x02000000)
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
//等待PLL锁定
}

#define  RCC_CFGR_SW                         ((uint32_t)0x00000003)
#define  RCC_CFGR_SW_PLL                     ((uint32_t)0x00000002)RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));//选择HSI作为系统时钟
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;  /*选择PLL输出作为时钟
相当于从HSI切换到PLL输出作为时钟*/

#define  RCC_CFGR_SWS                        ((uint32_t)0x0000000C)while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
//判断是不是PLL输出如果是那就跳出,不是那就一直在循环
}

10_Systemlnit时钟系统初始化函数相关推荐

  1. SystemInit()时钟系统初始化函数解析

    SystemInit()时钟系统初始化函数 SystemInit() 函数在 system_stm32f10x.h头文件中可以看到函数声明,函数实现是在system_stm32f10x.c源文件中 S ...

  2. SystemInit时钟系统初始化函数剖析

    SystemInit()函数: void SystemInit (void) {/* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;//把内部的 ...

  3. STM32工作笔记045---SystemInit时钟系统初始化函数剖析

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 systeminit这个函数对,时钟系统有配置,是通过配置寄存器实现的.

  4. 【STM32】:RCC时钟系统

    前言 时不可以苟遇,道不可以虚行. 一.时钟树框图 HSI 振荡器时钟 HSE 振荡器时钟 主 PLL (PLL) 时钟 以上三种时钟源可以用来驱动系统时钟(SYSCLK): 还有两个次级时钟源: 3 ...

  5. 正点原子STM32F103学习笔记(六)——时钟系统

    时钟系统 RCC: reset clock control 复位和时钟控制器. 注意: 任何一个外设在使用之前,必须首先使能其相应的时钟 时钟系统框图 图形含义 梯形灰色方块:选择器 蓝色框:时钟源 ...

  6. STM32的时钟系统RCC详细整理

    一.综述: 1.时钟源 在STM32中,一共有5个时钟源,分别是HSI.HSE.LSI.LSE.PLL. ①HSI是高速内部时钟,RC振荡器,频率为8MHz: ②HSE是高速外部时钟,可接石英/陶瓷谐 ...

  7. STM32的时钟系统RCC详细整理(转)

    一.综述: 1.时钟源 在 STM32 中,一共有 5 个时钟源,分别是 HSI . HSE . LSI . LSE . PLL . ①HSI 是高速内部时钟, RC 振荡器,频率为 8MHz : ② ...

  8. 【STM32】STM32F4时钟系统

    00. 目录 文章目录 00. 目录 01. STM32F4时钟系统概述 02. STM32F4时钟系统图 03. STM32F4时钟初始化配置 04. 时钟配置总结 05. 预留 06. 附录 07 ...

  9. 从头开始写STM32F103C8T6驱动库(二)——编写系统初始化程序,配置时钟树

    系列文章目录 Github开源地址 从头开始写STM32F103C8T6驱动库(一)--STM32CubeMX创建并调整工程结构 从头开始写STM32F103C8T6驱动库(二)--编写系统初始化程序 ...

最新文章

  1. oracle 数据库对于多列求最大值
  2. 日志平台(网关层) - 基于Openresty+ELKF+Kafka
  3. vscode怎么弄php,vscode如何设置语言
  4. python怎么保存文件代码_Python文件读写保存操作的实现代码
  5. 开发---推荐16个国外的源码下载网站
  6. SPOJ QTREE6 lct
  7. 多线程读取文件File
  8. JS-数组和函数冒泡排序递归函数
  9. 基于LiteOS Studio零成本学习LiteOS物联网操作系统
  10. python 单链表查找元素_如何在python中一次找到链表的中间元素?
  11. 2.5 指数加权平均的偏差修正
  12. struts1.2上传文件到服务器
  13. theano 编程细节
  14. join(long)与sleep(long)的区别
  15. php sub pos,PHP pos()用法及代码示例
  16. 第1章 游戏之乐——光影切割问题
  17. 判断变量是空_python基础(二):变量的数据类型、常量、操作符、分支、循环、条件判断...
  18. 10个谷歌浏览器调试技巧
  19. 软件测试-正交实验法设计测试用例
  20. js定义函数的两种形式及区别

热门文章

  1. 635头脑风暴创意法
  2. 2019适合创业的项目有哪些呢
  3. linux驱动开发学习笔记二十一:异步通知
  4. 星火燎原,遍地开花!2019链脉名片蓄势进发
  5. 如何在Word2007文档中不同页面纵横方向混排?
  6. 加装机械硬盘遇到的问题
  7. 遥感卫星遇上北斗导航卫星,将擦出怎样的火花?
  8. win10鼠标右键文件夹一直转圈圈
  9. 高效职业发展的七个习惯
  10. 举个栗子!Tableau 技巧(181):使用地图层标记,快速实现旭日图