在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main。那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使用库函数编写的LED程序,在system_stm32f10x.c文件中可以找到SystemInit()函数,SystemInit()代码如下:


void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
RCC->CR &= (uint32_t)0xEBFFFFFF;

/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x00FF0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined
STM32F10X_HD_VL)
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000;
#else
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined
STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in
Internal FLASH. */
#endif
}


SystemInit函数开始通过条件编译, 先复位RCC寄存器,同时通过设置CR寄存器的HSI时钟使能位来打开HSI时钟。默认情况下如果CR寄存器复位,是选择HSI作为系统时钟,这点大家可以查看RCC->CR寄存器相关位描述可以得知,当低两位配置为00的时候(复位之后),会选择HSI振荡器为系统时钟。也就是说,调用SystemInit函数之后,首先是选择HSI作为系统时钟。在设置完相关寄存器后才换成HSE作为系统时钟,接下来SystemInit函数内部会调用SetSysClock()函数。这个函数内部是根据宏定义设置系统时钟频率。函数如下:


static void SetSysClock(void)
{

#ifdef SYSCLK_FREQ_HSE

SetSysClockToHSE();

#elif defined SYSCLK_FREQ_24MHz

SetSysClockTo24();

#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72();
#endif

}


在system_stm32f10x.c文件的开头就有对此宏定义,系统默认的宏定义是72MHz,如下:


#define SYSCLK_FREQ_72MHz 72000000


如果你要设置为36MHz,只需要注释掉上面代码,然后加入下面代码即可:


#define SYSCLK_FREQ_36MHz 36000000


根据该函数内部实现过程可知,直接调用SetSysClockTo72()函数,此函数功能是将系统时钟SYSCLK设置为72M,AHB总线时钟设置为72M,APB2总线时钟设置为72M,APB1总线时钟设置为36M,PLL时钟设置为72M。函数具体实现大家可以打开库函数查看,这里我们就不截取出来。如果SystemInit内实现过程看不懂没有关系,大家只要知道SystemInit函数执行完,时钟大小设置如下:


SYSCLK(系统时钟) =72MHz
AHB 总线时钟(HCLK=SYSCLK) =72MHz
APB1 总线时钟(PCLK1=SYSCLK/2) =36MHz
APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz
PLL 主时钟 =72MHz


在STM32中,这些时钟值是要熟悉的。

STM32入门系列-STM32时钟系统,时钟初始化配置函数的更多相关文章

  1. STM32入门系列-STM32时钟系统,时钟使能配置函数

    之前的推文中说到,当使用一个外设时,必须先使能它的时钟.怎么通过库函数使能时钟呢?如需了解寄存器配置时钟,可以参考<STM32F10x中文参考手册>"复位和时钟控制(RCC)&q ...

  2. STM32入门系列-STM32时钟系统,自定义系统时钟

    在时钟树的讲解中我们知道,通过修改PLLMUL中的倍系数值(2-16)可以改变系统的时钟频率.在库函数中也有对时钟倍频因子配置的函数,如下: void RCC_PLLConfig(uint32_t R ...

  3. STM32入门系列-STM32时钟系统,STM32时钟树

    时钟对于单片机来说是非常重要的,它为单片机工作提供一个稳定的机器周期从而使系统能够正常运行.时钟系统犹如人的心脏,一旦有问题整个系统就崩溃.我们知道STM32属于高级单片机,其内部有很多的外设,但不是 ...

  4. STM32入门系列-STM32最小系统介绍

    STM32最小系统组成 单片机最小系统,也就是能够使得单片机正常运行程序,最少需要连接哪些器件.一般来说,STM32最小系统由四部分组成: 电源电路 复位电路 晶振电路 下载电路 STM32单片机由A ...

  5. STM32入门系列-STM32外设地址映射

    片上外设区分为四条总线,根据外设速度的不同,不同总线挂载着不同的外设,APB1挂载低速外设,APB2和AHB挂载高速外设.相应总线的最低地址我们称为该总线的基地址,总线基地址也是挂载在该总线上的首个外 ...

  6. CentOS7 系统服务器初始化配置、安全加固、内核升级优化常用软件安装的Shell脚本分享

    转载自:https://www.bilibili.com/read/cv13875630?spm_id_from=333.999.0.0 描述: 适用于企业内部 CentOS7 系列操作服务器初始化. ...

  7. C# 互操作性入门系列(二):使用平台调用调用Win32 函数

    好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...

  8. [转]C# 互操作性入门系列(二):使用平台调用调用Win32 函数

    传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...

  9. STM32入门-STM32时钟系统,时钟初始化配置函数

    在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main.那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使 ...

随机推荐

  1. gateway(二、过滤器)

    过滤器其实是路由转发+过滤器 自定义过滤器 首先创建一个类继承下边两个类,实现过滤器 然后在启动项中通过创建bean的方式创建路由器 @Componentpublic class TimeFilter ...

  2. Python-SyntaxError: invalid syntax

    Error:  SyntaxError: invalid syntax Where? 运行Python代码时候,提示错误 Way? Python def class if elif for while ...

  3. 一起构建Python生长土壤

    环境 环境安装 1. 解释器 Python https://www.python.org/ 2. IDE Pycharm https://www.jetbrains.com/pycharm/downl ...

  4. Book of Shaders 04 - 网格噪声:Worley Noise

    0x00 思路 假设要生成 4 个网格,可以先在空间中指定 4 个特征点.对于每个像素点,计算它到最近特征点的距离,将这个距离当作结果值输出. #ifdef GL_ES precision mediu ...

  5. Android 10不能使用uiautomatorviewer定位元素的终极解决方法

    Android app 元素定位除了使用Appium Inspector 外,还可以使用Android SDK 里tools中的uiautomatorviewer 工具.但今天打算使用 uiautom ...

  6. [Docker] redis 全配置

    启动容器,加载配置文件并持久化数据 docker run -d --privileged=true -p 6379:6379 --restart always -v /usr/redis/conf:/ ...

  7. 多测师讲解内置函数 _format_高级讲师肖sir

    #python中的格式化输出:format()# 和%号格式化输出一样,是%号的另外一种格式#1.不设置指定位置,按默认顺序 a ='{}'.format('hello','nihao','dajia ...

  8. 女儿拿着小天才电话手表问我App启动流程

    前言 首先,new一个女儿, var mDdaughter = new 女儿("6岁","漂亮可爱","健康乖巧","最喜欢玩小天 ...

  9. 云服务器、euleros系统自动断开连接解决方案

    我这里的云服务器,网上查的修改sshd.config文件并不有效 我提供另一种方法解决这个问题: vim /etc/profile 再最底部新增 export TMOUT=6000 #6000代表60 ...

  10. day35 Pyhton 网络编程02

    一内容回顾 网络基础 网络应用开发架构 B/S架构   浏览器直接作为客户端的程序 C/S架构 B/S是特殊的C/S osi七层模型 应用层  python代码   http  https  ftp  ...