Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【STM32H7教程】第14章 STM32H7的电源,复位和时钟系统

【STM32H7教程】第14章 STM32H7的电源,复位和时钟系统

作者头像
Simon223
发布于 2019-05-14 02:07:56
发布于 2019-05-14 02:07:56
1.6K00
代码可运行
举报
运行总次数:0
代码可运行

完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980

第14章       STM32H7的电源,复位和时钟系统

本章教程继续为大家讲解学习STM32H7的必备知识点电源,复位和时钟系统。掌握这三方面的知识点对后面的学习大有裨益。

14.1 初学者重要提示

14.2 电源

14.3 硬件复位

14.4 软件复位

14.5 RCC时钟控制

14.6 总结

14.1 初学者重要提示

1、  电源管理部分涉及到的各种低功耗方式会在后面章节中为大家讲解,当前阶段仅需了解低功耗属于电源管理部分即可。

2、  电源管理部分最繁琐的就是CPU,D1,D2,D3域的各种运行,待机,停机状态切换,这部分知识点也放在后面低功耗章节学习。

14.2 电源

电源是系统稳定运行的根本,主要分为以下几个知识点,电源供电、供电监控、电源管理和低功耗。当前阶段主要了解电源供电和硬件上电时序。

14.2.1 电源供电

学习STM32H7的电源供电,往往被一堆电源标识Vdd,Vdda,Vcap,Vss等搞迷糊,这些标识整明白了,电源供电部分也就理解了,首先看下面的框图:

这些常用标识的解释如下:

对于电源供电部分了解了这些知识点就够用。

14.2.2 系统上电启动

系统上电到程序开始运行期间,H7都做哪些工作,一张时序图可以说明问题:

对于上面的截图,主要看Operating mode部分,依次是Power down –> Reset -> Wait Oscillator ->HW system init -> Run -> Wait ACTVOS RDY –> Run,即断电状态 -> 复位状态 -> 等待HSI就绪->硬件初始化 -> 运行 -> 等ACTVOS位就绪 -> 正式运行。

详细些的执行流程如下:

  •   当系统上电后,POR(Power on reset 上电复位)会检测VDD供电,当VDD大于POR设置的阀值时,将使能电压稳压器,注意看VDD那条线的变化。
  •   看VCORE那条曲线,只要VOSRDY未就绪,就会一直处于复位状态。
  •   一旦VCORE正常输出,系统将走出复位状态,内部高速RC振荡器HSI将使能。
  •   HSI稳定后,将开始系统初始化,主要是Flash和可选字节的加载,这些都是由硬件完成的,CPU也将以受限的方式运行(主要是指不允许对RAM进行写操作)。
  •   软件程序初始化系统,包括供电配置。当供电配置完成后,等待ACTVOSRDY位置1,完成置1后,CPU就进入正常的运行的模式,允许读写RAM了。

14.2.3 电源管理

关于电源管理部分,H7参考手册中讲解的还挺复杂的,当前阶段我们仅需了解几个重要的工作状态即可,看到这几个单词了要认识,因为官方文档中多处要用这几个标识。

为了实现各种低功耗模式,CPU和D1,D2,D3域支持的各种模式如下:

  • CPU模式

CRun:运行状态,CPU和CPU子系统外设正常运行。

CSleep:休眠状态,CPU时钟停止运行,CPU子系统外设正常运行。

CStop:停止状态,CPU和CPU子系统外设都停止运行。

  • D1域模式

DRun:运行状态,D1域的总线矩阵正常运行,CPU子系统运行在CRun或者CSleep模式。

DStop:停机状态,D1域的总线矩阵时钟停止运行,CPU子系统运行在CStop模式,PDDS_D1位选择DStop模式。

DStandby:待机状态,D1域的总线矩阵断电,CPU子系统运行在CStop模式,PDDS_D1位选择DStandby模式。

  • D2域模式

DRun:运行状态,D2域的总线矩阵正常运行,CPU子系统在D2域中有分配的外设,CPU子系统运行在CRun或者CSleep模式。

DStop:停机状态,D2域的总线矩阵时钟停止运行,CPU子系统没有在D2域分配外设,PDDS_D1位选择DStop模式。或者CPU子系统在D2域中有分配的外设,CPU子系统运行在CStop模式,PDDS_D1位选择DStop模式。

DStandby:待机状态,D2域的总线矩阵断电,CPU子系统没有在D2域分配外设,PDDS_D1位选择DStandby模式。或者CPU子系统在D2域中有分配的外设,CPU子系统运行在CStop模式,PDDS_D1位选择DStandby模式。

  • 系统/D3域模式

Run:运行状态,系统时钟和D3域总线矩阵时钟处于运行状态。CPU子系统处于CRun和CSleep模式,或者一个唤醒信号处于激活状态。

Stop:停止状态,系统时钟和D3域总线矩阵时钟处于停止状态,CPU子系统处于CStop模式。所有的唤醒信号都处于非激活状态,并且至少某个域的一个PDDS_Dn位选择了Stop模式。

Standby:待机状态,系统处于断电状态,CPU子系统处于CStop模式,所有的唤醒信号都处于非激活状态,并且所有域的所有PDDS_Dn位选择Standby模式。

14.2.4 电源去耦电容的选择

每个电源对 (VDD/VSS, VDDA/VSSA ...)必须使用下述的滤波陶瓷电容去耦。这些电容必须尽量靠近芯片引脚,以确保器件正常工作。不建议去掉滤波电容来降低PCB 尺寸或成本,这可能导致器件工作不正常。 

14.3 硬件复位

所有数字计算机系统都是由某种形式的震荡时钟电路驱动的。这种电路被称为系统的“脉搏”,是系统正确运行的关键。如果振荡器失灵,系统将完全无法运行,如果振荡器运行不规律,系统执行的所有与时间有关的计算都会有误差。

所有微控制器的启动流程都不通用。由于硬件的复杂性,必须运行一段由厂家定义的短小的“复位程序”来使硬件处于一种正确的状态,然后再开始执行用户程序。运行这个复位程序需要时间并且要求微控制器的振荡器已经运行。

当系统由可靠的电源供电时,一旦通电,电源迅速地达到额定输出电压,一旦断电,电源迅速地下降到0V,并且在接通的时候,电压不会降低。这时能够可靠地使用基于一个电容和一个电阻的低成本硬件复位。这种形式的复位电路称为阻容复位。

如果电源不够可靠,而涉及安全性,这种简单的阻容解决方案就不合适了。

14.3.1 上电复位和手动复位

STM32H7开发板的硬件复位原理图如下:

  •   STM32这款CPU的复位引脚是低电平有效,即NRST为低电平时,CPU处于复位状态。
  •   R173单的RC复位电路。当系统上电瞬间,C114电容两端电压可以认为是0,CPU处于复位状态。3.3V电源通过R173给C114充电,当C114的电压升到CPU的高电平门槛电压时,CPU退出复位状态转入运行状态。
  •   在设计电路时,需要选择适当的R值和C值,以保证NRST低电平持续时间满足CPU复位最小脉宽的要求。
  •   当按下S4轻触开关时,C114两端被短路接地,可实现手动复位CPU。

注,根据需要,大家也可以使用STM32H7 NRST引脚的内部上拉:http://forum.armfly.com/forum.php?mod=viewthread&tid=9314

14.3.2 复位序列

前面第11章的13.3.1小节讲解了复位系列的相关知识,再结合本章节的上电复位和下电复位,大家会对其有一个较全面的认识,更多复位序列的知识直接看13.3.1小节即可。

14.4 软件复位

除了上电和手动复位,程序设计设置中还经常要用到软件复位,即调用一条函数就可以实现复位功能。此函数已经由CMSIS软件包中的core_cm7.h文件提供,函数如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
  \brief   System Reset
  \details Initiates a system reset request to reset the MCU.
 */
__STATIC_INLINE void __NVIC_SystemReset(void)
{
  __DSB();                                  /* Ensure all outstanding memory accesses included
                                              buffered write are completed before reset */
  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
                            SCB_AIRCR_SYSRESETREQ_Msk    );        /* Keep priority group unchanged */
  __DSB();                                                         /* Ensure completion of memory access */

  for(;;)                                                          /* wait until reset */
  {
    __NOP();
  }
}

软件复位反映到实际硬件上,就是给硬件复位部分发一个复位信号:

14.5 RCC时钟控制

STM32H7有如下六种时钟可供使用:

  •   HSI (High-speed internal oscillator) :

HSI是内部的高速RC振荡器,频率64MHz,可被用于系统时钟。优势是低成本,无需外部时钟,快速启动(仅需几个微秒),缺点是精度差,即使经过校准。

  •   HSE (High-speed external oscillator):

HSE是外部的高速振荡器,通过外接时钟源,有源或者无源晶振驱动,时钟范围4-48MHz。优势是精度高,缺点是增加成本。

  •   LSE (Low-speed external oscillator)

LSE是外部的低速振荡器,通过外接时钟源,有源或者无源晶振驱动,一般接32.768KHz,主要用于RTC实时时钟。

  •   LSI (Low-speed internal oscillator)

LSI是内部的低速RC振荡器,频率约是32KHz,主要用于独立看门狗和自动唤醒,也可以用于RTC实时时钟。

  •   CSI (Low-power internal oscillator)

CSI是内部的低速振荡器,频率约是4MHz,相比64MHz的HSI,主要用于低功耗。

  •   HSI48 (High-speed 48 MHz internal oscillator)

HSI48是内部高速振荡器,频率约是48MHz,用于给特定的外设提供时钟,比如USB。

通过下面的时钟树再进一步的认识这几个时钟:

14.5.1 HSE和LSE硬件设计

  • HSE时钟

当前V7开发板是用的25MHz晶振为HSE提供时钟,硬件设计如下:

晶振和负载电容需要尽可能近地靠近H7的晶振引脚,以减小输出失真和启动稳定时间。负载电容值必须根据选定的晶振进行调节。 

对于C15和C17,我们推荐使用高质量陶瓷电容,这种电容是设计用于需要高频率的场合,并且可以满足晶体或谐振器的需求。C15和C17通常具有相同的值。

这里再额外补充一个知识点,HSE旁路时钟和外置晶振区别:当前V7板子是采用的外置晶振模式,高速外部 (HSE) 时钟可以使用一个4到48MHz 的晶振 / 陶瓷谐振振荡器产生:

而bypass 旁路的意思就是不使用它,绕过它。具体到HSE旁路的话,用户直接提供4-50MHz的时钟源即可,可以使用有源晶振或者FPGA提供时钟等方式:

  • LSE时钟

当前V7开发板是用的32768Hz晶振为LSE提供时钟,硬件设计如下:

STM32的LSE晶振起振难(又称RTC起振)是老毛病了,选取晶振和配套电容比较讲究,最好按照ST提供的厂家和配套电容选取:http://forum.armfly.com/forum.php?mod=viewthread&tid=87673

14.5.2 时钟配置

STM32H7开发板使用的外部晶振频率是25MHz,下面分步说明如何让其通过这个频率工作到400MHz的主频。

  •   第1步:在stm32h7xx_hal_conf.h文件配置HSE_VALUE

配置的大小要跟板子的实际晶振大小匹配。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#if !defined  (HSE_VALUE) 
#define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
  •   第2步:系统上电后,在启动文件startup_stm32h743xx.s的复位中断服务程序里面会调用函数SystemInit。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Reset_Handler    PROC
                 EXPORT  Reset_Handler                    [WEAK]
        IMPORT  SystemInit
        IMPORT  __main

                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

以往STM32F1和STM32F4系列都会在函数SystemInit里面配置PLL锁相环,使用了HAL后,需要在main函数里面配置。当前SystemInit函数实现的功能如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1.    /**
2.      * @brief  Setup the microcontroller system
3.      *         Initialize the FPU setting, vector table location and External memory
4.      *         configuration.
5.      * @param  None
6.      * @retval None
7.      */
8.    void SystemInit (void)
9.    {
10.      /* FPU settings ------------------------------------------------------------*/
11.      #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
12.        SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
13.      #endif
14.      /* Reset the RCC clock configuration to the default reset state ------------*/
15.      /* Set HSION bit */
16.      RCC->CR |= RCC_CR_HSION;
17.    
18.      /* Reset CFGR register */
19.      RCC->CFGR = 0x00000000;
20.    
21.      /* Reset HSEON, CSSON , CSION,RC48ON, CSIKERON PLL1ON, PLL2ON and PLL3ON bits */
22.      RCC->CR &= (uint32_t)0xEAF6ED7F;
23.    
24.      /* Reset D1CFGR register */
25.      RCC->D1CFGR = 0x00000000;
26.    
27.      /* Reset D2CFGR register */
28.      RCC->D2CFGR = 0x00000000;
29.    
30.      /* Reset D3CFGR register */
31.      RCC->D3CFGR = 0x00000000;
32.    
33.      /* Reset PLLCKSELR register */
34.      RCC->PLLCKSELR = 0x00000000;
35.    
36.      /* Reset PLLCFGR register */
37.      RCC->PLLCFGR = 0x00000000;
38.      /* Reset PLL1DIVR register */
39.      RCC->PLL1DIVR = 0x00000000;
40.      /* Reset PLL1FRACR register */
41.      RCC->PLL1FRACR = 0x00000000;
42.    
43.      /* Reset PLL2DIVR register */
44.      RCC->PLL2DIVR = 0x00000000;
45.    
46.      /* Reset PLL2FRACR register */
47.    
48.      RCC->PLL2FRACR = 0x00000000;
49.      /* Reset PLL3DIVR register */
50.      RCC->PLL3DIVR = 0x00000000;
51.    
52.      /* Reset PLL3FRACR register */
53.      RCC->PLL3FRACR = 0x00000000;
54.    
55.      /* Reset HSEBYP bit */
56.      RCC->CR &= (uint32_t)0xFFFBFFFF;
57.    
58.      /* Disable all interrupts */
59.      RCC->CIER = 0x00000000;
60.    
61.      /* Change  the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
62.      *((__IO uint32_t*)0x51008108) = 0x00000001;
63.    
64.    #if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
65.      SystemInit_ExtMemCtl();
66.    #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
67.    
68.      /* Configure the Vector Table location add offset address ------------------*/
69.    #ifdef VECT_TAB_SRAM
70.      SCB->VTOR = D1_AXISRAM_BASE  | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal ITCMSRAM */
71.    #else
72.      SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
73.    #endif
74.    
75.    }

第12行:使能FPU单元。

第16 – 59行:复位RCC相关寄存器。

第62行:这条语句在这里的作用涉及到STM32H7硬件版本Y的一个bug解决方案,详情可以看这个帖子:http://forum.armfly.com/forum.php?mod=viewthread&tid=87346

第69 – 73行:设置中断向量表的位置。

  •   第3步:在main函数的外设驱动初始化函数里面完成时钟初始化,主要是PLL锁相环,让芯片最终工作到400MHz。

14.6 总结

本章节就为大家讲解这么多,本章节的知识点相对比较多,比较杂,不容易一下子都掌握了。随着后面章节的进行,还会深入的讲解这些知识点。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-04-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
这MySQL里的反斜杠(\\)也太坑了吧!!真是醉了
  后来发现,原因其实很简单,在MySQL中,反斜杠在字符串中是属于转义字符,经过语法解析器解析时会进行一次转义,所以当我们insert反斜杠(\)字符时,如 insert “\” 在数据库中最终只会存储"",第一个反斜杠(\)被当做转义字符处理。
陈哈哈
2021/10/13
4.6K0
Python|Python基本数据类型
字符串类型 str 是常用的数据类型之一,开发者可以使用引号(单引号或双引号)来创建字符串。创建python字符串的方法非常简单,只需为变量分配一个值即可。
Java小技巧
2022/05/23
6630
Python|Python基本数据类型
java基础学习_概述_day01总结
============================================================================= ============================================================================= 涉及到的知识点有:   1:计算机概述(了解)   2:键盘功能键的认识和快捷键(掌握)   3:常见的DOS命令(掌握)   4:Java语言概述(了解)   5:JVM,JRE,JDK的作用及
黑泽君
2018/10/11
5780
10个正则表达式技巧
=零或更多 =还有一个?= 0或1 {3} =正好3倍{2,4} =两倍,三倍或四倍{2,} =两倍或更多倍
前端开发博客
2020/11/04
1.2K0
10个正则表达式技巧
Python : 反斜杠
使用python写字符串常量时,raw string是个很好用的东东,比如在C里我要写一个Windows下的路径,得这么
py3study
2020/01/07
4K0
Python 编程中反斜杠 “\” 的作用:作为续行符和转义字符,处理文件路径和正则表达式时需特别注意。
Python 中的反斜杠 \ 可以被用作续行符,它允许你将一行代码分成多行来书写,以提高代码的可读性。这在处理长字符串、复杂的数学表达式或其他需要多行布局的代码时非常有用。
叶庭云
2024/05/25
8.8K0
Python 编程中反斜杠 “\” 的作用:作为续行符和转义字符,处理文件路径和正则表达式时需特别注意。
传智播客_风清扬_2015年java基础深入浅出版_刘意老师
视频百度网盘下载链接:https://pan.baidu.com/s/1pLc7AvL#list/path=%2F
黑泽君
2018/10/11
4.1K1
Windows文件名非用反斜杠?Python小技巧帮你解决这个麻烦
在编程过程中,我们往往会遇到一个小麻烦——微软 Windows 系统在文件夹名之间使用反斜杠字符,而几乎所有其它的计算机(操作系统)都使用正斜杠:
机器之心
2019/07/24
1.8K0
Windows文件名非用反斜杠?Python小技巧帮你解决这个麻烦
正斜杠和反斜杠的区别_vb斜杠和反斜杠
参考链接: 正斜杠/和反斜杠\的区别 https://www.cnblogs.com/codingmengmeng/p/6179822.html
全栈程序员站长
2022/09/20
2.6K0
正斜杠和反斜杠的区别_vb斜杠和反斜杠
《Linux命令行与shell脚本编程大全》第二十章 正则表达式
20.1 什么是正则表达式 20.1.1 定义 正则表达式是你所定义的模式模板。linux工具可以用它来过滤文本。 正则表达式利用通配符来描述数据流中第一个或多个字符。 正则表达式模式含有文本或特殊字符,为sed编辑器和gawk程序定义了一个匹配数据时采用的模板。 20.1.2 正则表达式的类型 使用正则表达式最大的问题在于有不止一种类型的正则表达式。 正则表达式是通过正则表达式引擎实现的,正则表达式引擎是一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配。 在linux中有两种流行的正则表达式
xcywt
2018/01/11
1.3K0
Python 基础篇-正斜杠("/")和反斜杠("\")的用法
今天为大家讲一讲正反斜杠的常见应用:一个就是路径里的应用,还有就是反斜杠在正则表达式里的不同。
小蓝枣
2020/09/23
7.4K0
Linux笔记5.展开与引用
参数展开 路径名展开 [root@senlong usr]# echo * bin etc games include lib lib64 libexec local man sbin share src tmp 为何echo不打印 * ?是因为shell把 * 展开成了另外的东西(在这种情况下,就是在当前工作目录下的文件名字) 这种通配符工作机制叫做路径名展开 [root@senlong usr]# echo l* lib lib64 libexec local 算术表达式展开 shell 允许算术表达式
章鱼喵
2018/06/27
7910
python学习第四讲,python基础语法之判断语句,循环语句
if是判断条件成立该执行那个代码块, else 则是不成立则执行那个代码块 语法如下:
IBinary
2019/05/25
7910
第八章:从 shell 眼中看世界
In this chapter we are going to look at some of the “magic” that occurs on the commandline when you press the enter key. While we will examine several interesting andcomplex features of the shell, we will do it with just one new command:
砖业洋__
2023/05/06
2560
C语言 “入门” 章节的全知识点
注意后缀! 如果是以.cpp为后缀 编译器会按照C++编译 如果是以C为后缀 就是C语言
2024/04/30
1660
C语言 “入门” 章节的全知识点
《Python完全自学教程》免费在线连载4.2.2
出现了 SyntaxError(语法错误)引导的提示, SyntaxError 是一种错误类型(参阅第10章10.1节),其后的内容是对此错误的解释:“invalid syntax”(无效的语法)。
老齐
2022/04/01
6040
Linux:进程概念(四.main函数的参数、环境变量及其相关操作)
main() 函数是 C 和 C++ 程序中的入口函数,通常用于表示程序的起始点。在 C 和 C++ 中,main() 函数可以有两种不同的形式:
是Nero哦
2024/05/25
2420
Linux:进程概念(四.main函数的参数、环境变量及其相关操作)
【python入门到精通】python常用数据类型详解(二)
整型(Int) - 通常被称为是整型或整数,是正或负整数,不带小数点。Python3 整型是没有限制大小的,可以当作 Long 类型使用,所以 Python3 没有 Python2 的 Long 类型。
大数据小禅
2021/12/20
1K0
正则表达式(RegEx)官方手册/权威指南【Python】
正则表达式(称为RE,或正则,或正则表达式模式)本质上是嵌入在Python中的一种微小的、高度专业化的编程语言,可通过 re 模块获得。 使用这种小语言,你可以为要匹配的可能字符串集指定规则;此集可能包含英语句子,电子邮件地址,TeX命令或你喜欢的任何内容。 然后,您可以询问诸如“此字符串是否与模式匹配?”或“此字符串中的模式是否匹配?”等问题。 你还可以使用正则修改字符串或以各种方式将其拆分。
sunsky
2020/08/20
5.9K0
正则表达式(RegEx)官方手册/权威指南【Python】
Linux命令(32)——grep命令
grep(Globally search a Regular Expression and Print)是GNU开发的一款免费开源的文本搜索工具。grep家族包括grep、egrep和fgrep。其功能是在指定的文件中查找一个指定格式或者内容的字符串,并将匹配的字符串所在行打印出来。如果不指定任何文件名称,或给定的文件名为“-”,则从标准输入设备读取数据。grep支持正则表达式搜索文本。
恋喵大鲤鱼
2018/08/03
4.5K0
推荐阅读
相关推荐
这MySQL里的反斜杠(\\)也太坑了吧!!真是醉了
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验