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

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

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

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

目录

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

14.1 初学者重要提示

14.2 电源

14.2.1 电源供电

14.2.2 系统上电启动

14.2.3 电源管理

14.2.4 电源去耦电容的选择

14.3 硬件复位

14.3.1 上电复位和手动复位

14.3.2 复位序列

14.4 软件复位

14.5 RCC时钟控制

14.5.1 HSE和LSE硬件设计

14.5.2 时钟配置

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://www.armbbs.cn/forum.php?mod=viewthread&tid=93144

14.3.2 复位序列

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

14.4 软件复位

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

/**
  \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://www.armbbs.cn/forum.php?mod=viewthread&tid=87673

14.5.2 时钟配置

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

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

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

#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。
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函数实现的功能如下:

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://www.armbbs.cn/forum.php?mod=viewthread&tid=87346

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

 

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

14.6 总结

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

 

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值