STM32-时钟篇以及复位时时钟的配置过程

时钟就是一个芯片的心脏,CPU的处理速度也是由时钟来直接决定,相比51单一的时钟源,STM32具有强大的时钟系统,我们的所有的外设都离不开时钟,时钟是学习STM32非常重要的部分。

一、时钟源

首先时钟都是由时钟源产生的,STM32的时钟可以由三个时钟源产生。

二、时钟树

在STM32的官方参考手册里面,RCC时钟的这一节里面有一个时钟树的图,如下,如果可以看懂这个图的话,就对STM32的时钟系统有了很清晰的了解,下面将会分部分对时钟树比较重要的部分进行简单的讲解。

1. 系统时钟部分

系统时钟部分一般被配置为72MHz,如下图,一般是由HSE(8MHz)经过PREDIV1不进行分频,然后经过PLLMUL进行9倍频,然后得到72MHz的系统时钟SYSCLK。

2. 实时时钟部分

如下图,实时时钟的时钟RTCCLK可以来源于三个地方,分别是40kHz的LSI(内部低速振荡器)和32.768kHz的LSE(外部低速振荡器)以及由HSE(外部高速振荡器进行128分频得到的时钟)。

3. APB1、APB2、AHB三条总线的时钟

  1. AHB 总线时钟:AHB时钟即HCLK,直接来源于系统时钟可以选择进行分频,一般不分频,等于系统时钟的最高频率72MHz。
  2. APB1总线的时钟:即PCLK1,最高只能设置为36MHz,来源于AHB的时钟HCLK,可以选择进行分频,由于最高只能设置为36MHz,所以一般进行2分频得到PCLK1=36MHz。
  3. APB2总线的时钟:即PCLK2,最高可以设置为72MHz,来源于AHB的时钟HCLK,可以选择进行分频。

4. 定时器的时钟

定时器又分为高级定时器和通用定时器,高级定时器包括TIM1和TIM8,通用定时器包括TIM2~TIM7
如图中所示,如果APB1总线的预分频系数为1,那么到通用定时器的时钟就等于APB1总线的时钟PCLK1,否则等于APB1总线的时钟PCLK1*2。例如,APB1的时钟PCLK1配置为最高36MHz,APB1 prescaler=1那么通用定时器的时钟TIMxCLK=PCLK1=36MHz;如果APB1 prescaler不等于 1,那么TIMxCLK=PCLK1×2=72MHz。
与高级定时器有关的总线是APB2,和通用定时器类似,如果APB2总线的预分频系数为1,那么到通用定时器的时钟就等于APB2总线的时钟PCLK2,否则等于APB2总线的时钟PCLK2*2。有同学在这里可能会有一点点不了解,因为APB2总线的最高频率为72MHz,在这里乘以2,就是144MHz,这样理解是不对的,为什么呢?首先只有APB2 prescaler 不为1的后,才会乘以2,而系统时钟最高为72MHz,如果APB2 prescaler不为1,那么会被分频,然后到定时器的时钟再乘以2,也是始终不会超过72MHz的。

5. ADC的时钟

ADC的时钟没有什么好说的,就是来源于APB2,然后经过ADC的预分频器,得到ADCCLK,不过需要注意的是ADC的最高频率只能为14MHz,当APB2的频率为72MHz的时候,必须经过6分频,得到的是12MHz,通过自己实验以及在网上查找资料发现,即使没有经过6分频,ADC还是可以正常工作,但是需要注意的是,此时ADC会有误差。

三、系统复位时时钟的配置过程

在编写STM32的时候,会有一个启动文件startup_stm32f10x_md.s,关于启动文件的作用如下

  1. 初始化堆栈指针 SP;
  2. 初始化程序计数器指针 PC;
  3. 设置堆、栈的大小;
  4. 设置异常向量表的入口地址;
  5. 配置外部 SRAM 作为数据存储器(这个由用户配置,一般的开发板可没有外部 SRAM);
  6. 设置 C 库的分支入口__main(最终用来调用 main 函数);
  7. 在 3.5 版的启动文件还调用了在 system_stm32f10x.c 文件中的
    SystemInit() 函数配置系统时钟,在旧版本的工程中要用户进入
    main 函数自己调用 SystemInit() 函数。
    这次我们的重点不放在启动文件上面,主要是系统初始化函数SystemInit() ,我们在启动文件中可以找到一段代码,意思就是首先调用了SystemInit函数,返回之后,就进入我们的主函数main。我们定位到SystemInit鼠标右键选择go to definition of ‘SysttemInit’或者按键盘上面的F12进入该函数。

    由于本篇针对的是STM32F103实用系列,函数里面一些是关于其他系列如互联型等,所以可以将SystemInit函数进行了一些简化,代码如下(来源于野火):
static void SetSysClockTo72(void)
{__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    /* 使能 HSE */    RCC->CR |= ((uint32_t)RCC_CR_HSEON);/* 等待HSE就绪并做超时处理 */do{HSEStatus = RCC->CR & RCC_CR_HSERDY;StartUpCounter++;  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET){HSEStatus = (uint32_t)0x01;}else{HSEStatus = (uint32_t)0x00;}  // 如果HSE启动成功,程序则继续往下执行if (HSEStatus == (uint32_t)0x01){/* 使能预取指 */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    /* HCLK = SYSCLK = 72M */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK = 72M */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK = 36M*/RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;/*  锁相环配置: PLLCLK = HSE * 9 = 72 MHz */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);/* 使能 PLL */RCC->CR |= RCC_CR_PLLON;/* 等待PLL稳定 */while((RCC->CR & RCC_CR_PLLRDY) == 0){}    /* 选择PLLCLK作为系统时钟*/RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* 等待PLLCLK切换为系统时钟 */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}}else{ /* 如果HSE 启动失败,用户可以在这里添加处理错误的代码 */}
}

这样我们就可以清楚的知道,搞明白了这些,这样在以后学习定时器或者ADC以及其他的资源的时候,就不会感觉到有一些迷惑,总是觉得不太自信的赶脚。。。哈哈

HCLK = SYSCLK = 72M
PCLK2 = HCLK = 72M
PCLK1 = HCLK = 36M
PLLCLK = HSE * 9 = 72 MHz

STM32-时钟篇以及复位时时钟的配置过程相关推荐

  1. 十、【高级篇】RTC--实时时钟

    RTC--实时时钟 RTC简介 查找RTC的时钟频率 查找RTC的计数值范围 初始化RTC 转换获取时间 主函数OLED显示实时时钟 RTC简介 RTC叫做REAL TIME CLOCK,是实时时钟, ...

  2. flask 第八篇 实例化flask时的参数配置

    Flask 是一个非常灵活且短小精干的web框架 , 那么灵活性从什么地方体现呢? 有一个神奇的东西叫 Flask配置 , 这个东西怎么用呢? 它能给我们带来怎么样的方便呢? 首先展示一下: from ...

  3. STM32F429第七篇之RCC(复位与时钟)

    文章目录 前言 更新 复位 系统复位 电源复位 备份域复位 时钟 时钟树图 时钟源 A 高速外部时钟HSE B 低速外部时钟LSE C 高速内部时钟HSI D 低速内部时钟LSI 外接时钟信号 MCO ...

  4. 基础——MCU的电源,复位和时钟系统(STM32为例)

    目录 1. 电源供电 2. 上电复位和手动复位 2.1 硬件复位 2.2 软件复位 3.1 晶振 3.2 内部时钟和外部时钟的不同 3.3 HSE和LSE外部电路的硬件设计 3.4 时钟具体理解 4. ...

  5. STM32基础10--实时时钟(RTC)

     目录 前言 RTC框图 STM32实时时钟电路 功能需要 STM32CubeMx配置RTC 配置RCC 配置RTC 配置时间,闹钟,唤醒 开启中断 设置中断优先级 功能代码实现 STM32Cude生 ...

  6. STM32复位与时钟、定时器

    复位与时钟     1>复位         1,上电复位:MCU当NRST为低电平时产生复位,而C35电容在上电瞬间,快速充电,相当于短路,GND的0v提供给NRST,MCU处于复位状态,当C ...

  7. proteus仿真STM32时时钟问题解决方案

    问题:在使用proteus仿真STM32时,发现外部时钟启动出错导致时钟频率不对,延时函数不准.影响外设的正常使用: 解决方法:使用STM32内部时钟作为系统时钟,可以解决此问题,但是没办法使用过高的 ...

  8. STM32MP157系列教程连载-硬件设计篇3:STM32MP1微处理器之时钟篇

    STM32MP157系列教程连载-硬件设计篇3:STM32MP1微处理器之时钟篇 一.RCC系统概述 本文涉及的内容主要包含在以下几个文档中,文档可从ST官方网站与意法半导体stm32中国下载. 序号 ...

  9. STM32学习总结(一)——时钟RCC

    系列文章目录 第一章 STM32学习总结(一)--时钟RCC 文章目录 目录 前言 二.STM32时钟树 1.时钟树 2.时钟源 3.时钟系统 三.STM32时钟配置 1.系统时钟配置 2.外设时钟配 ...

最新文章

  1. user agent stylesheet对格式的影响
  2. java设计模式---合成模式2
  3. Express-router
  4. GNU cflow实现调用关系分析
  5. Access导入SQL2005
  6. wxpython窗口固定大小_调整wxPython窗口的大小
  7. 第七次全国人口普查公报(第三号) ——地区人口情况
  8. Android知识笔记:特效系列,仿instagram文字排版特效,android应用开发基础学堂在线答案
  9. nbu备份本机oracle,nbu 7.1 备份恢复ORACLE实践手册
  10. 如何从技术上分析舌战群儒?
  11. 考研英语 - advanced
  12. 什么原因造成家里的WiFi网速慢?
  13. 综述论文要写英文摘要吗_关于小论文的一些撰写建议!
  14. shell 中的单行注释和多行注释
  15. 有哪些高性价比的LoRa模块?
  16. python--Folium
  17. PHP水仙花数程序设计思路,php实现水仙花数示例分享
  18. Html table添加空行
  19. 京东店铺人群标签如何优化?
  20. python将txt中的内容导入到excel

热门文章

  1. 一分钟了解勒索病毒WannaCry(永恒之蓝)
  2. 给计算机主机吹灰,电脑清灰教程:电脑主机怎么清理灰尘?台式电脑主机清理灰尘教学...
  3. Bootstrap人民币玩家攻略
  4. Python - Pandas
  5. java正则判断日期格式_Java中用正则表达式判断日期格式是否正确
  6. moviepy中3种不同的视频拼接方法
  7. 详细教你如何部署ICE服务(三)---IceBox框架 Ice Registry服务注册中心的联合使用
  8. 从零开始的腾讯云使用体验-4-搭建nginx+uwsgi+django
  9. 【Excel函数】Office 365 之Excel函数之Left函数
  10. Xcode5 及 Mac109下载地址