当前位置: 首页 > news >正文

江协科技STM32 13-1 PWR电源控制

PWRPower Control),意思是电源控制。PWR的作用就是负责管理STM32内部的电源供电部分,可以实现可编程电压监测器和低功耗模式的功能。可编程电压监测器(PVD)可以监控VDD电源电压,当VDD下降到PVD阀值以下或上升到PVD阀值之上时,PVD会触发中断,用于执行紧急关闭任务。这个功能预想的场景应该是使用电池供电或者对安全要求比较高的设备,如果供电电压在逐渐下降,在电压过低的情况下,可能会导致内部或者外部电路发生不确定的错误,为了避免不确定的因素,在电源电压低于设定的阈值时,我们可以主动出击,提前发出警告,并且关闭比较危险的设备。低功耗模式包括睡眠模式(Sleep)、停机模式(Stop)和待机模式(Standby),可在系统空闲时,降低STM32的功耗,延长设备使用时间。对于一些电池供电且绝大部分时间处于空闲状态的设备来说,我们需要这样的低功耗模式,在空闲状态时关闭不必要的硬件,比如直接把CPU断电或关闭时钟,这样程序自然就不会运行了。但是在低功耗模式下,我们也需要保留必要的唤醒电路,比如串口接收数据的中断唤醒、外部中断唤醒、RTC闹钟唤醒等等,在需要设备工作时,STM32能够立刻重新投入工作,这样才行。

接着我们来看下面的框图,这个图就是STM32内部的供电方案。整体上看此图可以分为三部分,最上面是模拟部分供电,叫做VDDA(VDD Analog);中间是数字部分供电,包括两块区域,VDD供电区域和1.8V供电区域;下面是后备供电,叫做VBAT(V Battery)。

VDDA供电区域主要负责模拟部分的供电,其中包括AD转换器、温度传感器、复位模块、PLL锁相环,这些设备的供电正极是VDDA,负极是VSSA,其中AD转换器还要两根参考电压的供电脚VREF+和VREF-,这两个脚在引脚多的型号里会单独引出来,在引脚少的型号,VREF+和VREF-在内部就已经分别接到了VDDA和VSSA了。然后看中间部分的供电,这一块由两部分组成,左边部分是VDD供电区域,其中包括IO电路、待机电路、唤醒逻辑和独立看门狗,右边部分是VDD通过电压调节器,降压到1.8V,提供给后面这一块的1.8V供电区域。1.8V区域包括CPU核心、存储器和内置数字外设。可以看出,STM32内部的大部分关键电路,CPU、存储器和外设,其实都是以1.8V的低电压运行的,当这些外设需要与外界进行交流时,才会通过IO电路转换到3.3V。所以我们从外部看好像STM32内部全是3.3V,但实际上它内部的CPU、外设都是1.8V供电运行。然后电压调节器,它的作用是给1.8V区域供电。最下面就是我们上一节提到的VBAT后备供电区域了,其中包括LSE 32K晶体振荡器、后备寄存器、RCC BDCR寄存器和RTC。RCC BDCR是RCC的寄存器,叫备份域控制寄存器。然后中间和下面之间有一个低电压检测器,可以控制开关,VDD有电时由VDD供电,VDD没电时由VBAT供电。

接下来我们来看本节课的重点:低功耗模式。下表是低功耗模式一览,表中第一列是有哪几种模式;第二列是如何配置,才能进入我们想要的模式;第三列是对于这些模式,进入之后,如何去唤醒;最后三列是每种模式对电路的操作。

低功耗模式有3种:睡眠、停机和待机,这三种模式从上到下关闭的电路越来越多,对应的从上到下,是越来越省电;同时从上到下也是越来越难唤醒的。

对于睡眠模式,直接调用WFI或者WFE即可进入,这两个是内核的指令,对应库函数里有对应的函数。其中WFI的意思是Wait For Interrupt,等待中断,意思就是我先睡了,如果有中断发生的话再叫我起来,所以对应的唤醒条件是任一中断。调用WFI进入的睡眠模式,任何外设发生任何中断时,芯片都会立刻醒来,因为中断发生了,所以醒来之后的第一件事就是处理中断函数;WFE的意思是Wait For Event,等待事件,对应的唤醒条件是唤醒事件,这个事件可以是外部中断配置为事件模式,也可以是使能了中断但是没有配置NVIC。调用WFE进入的睡眠模式,产生唤醒事件时会立刻醒来,醒来之后一般不需要进中断函数,直接从睡的地方继续运行。睡眠模式对电路的影响就是只把CPU时钟关了,对其他电路没有任何操作。表中最右侧的电压调节器刚才提到过,它实际上就是1.8V区域的电源,如果电压调节器关,就代表直接把1.8V区域断电;在普通的睡眠模式下,还有一个细分的功能,通过SLEEP-ON-EXIT位来决定,这一位=0时,无论程序在哪里调用WFI/WFE,都会立刻进入睡眠;这一位=1时,执行WFI/WFE之后,它会等待中断退出,等所有中断处理完成之后,再进入睡眠,这个设计可能考虑到中断还有一些紧急的任务,最好不要被睡眠打断了,所以先等等也无妨。

下面我们看到停机模式,如何进入停机模式呢?首先,SLEEPDEP位设置为1,高速CPU,你可以放心地睡,进入深度睡眠模式。另外PDDS这一位用来区分它是停机模式还是下面的待机模式:PDDS=0,进入停机模式,PDDS=1,进入待机模式;LPDS用来设置最后的电压调节器是开启还是进入低功耗模式:LPDS=0,电压调节器开启;LPDS=1,电压调节器进入低功耗。最后当我们把这些位设置好了,最后再调用WFI或者WFE,芯片就可以进入停机模式了。然后对于停机模式的唤醒,因为这个模式下芯片睡的更深,关的东西更多,所以唤醒条件要苛刻些,是任一外部中断唤醒,而其他中断唤醒不了。由于PVD、RTC闹钟、USB唤醒、ETH唤醒借道了外部中断,所以这4个信号,也可以唤醒停止模式。停止模式对电路有哪些操作呢?首先关闭所有1.8V区域的时钟,意思就是不仅CPU不能运行了,外设也运行不了了,定时器在计时的会暂停,串口收发数据也会暂停,不过由于没关闭电源,所以CPU和外设的寄存器数据都是维持原状的。之后HSI和HSE的振荡器关闭,既然CPU和外设时钟都关了,那这两个高速时钟显然也没用了。最后电压调节器可以选择开启或者处于低功耗模式,由刚刚说过的LPDS来控制。这个开启和低功耗模式两者有什么区别呢?其实区别不大,电压调节器无论是开启还是低功耗模式,都可以维持1.8V区域寄存器和存储器的数据内容,区别就是低功耗模式更省电些,同时低功耗模式在唤醒时,要花更多的时间,开启状态则相反。

最后我们看第三种,待机模式。其进入方式和停机模式差不多。首先也是SLEEPDEP位设置为1,即将深度睡眠。然后PDDS置1,表示即将进入待机模式,最后调用WFI或者WFE,就可以进入待机模式了。然后看一下唤醒条件,普通外设的中断和外部中断都无法唤醒待机模式,待机模式只有框中的指定信号才能唤醒:第一个是WKUP引脚的上升沿;第二个是RTC闹钟事件,我们在上节RTC种提到过;第三个是NRST引脚上的外部复位,意思就是按一下复位键,它也是能唤醒的;最后一个IWDG独立看门狗复位。之后待机模式对电路的操作基本上是能关的全关了,1.8V区域的时钟关闭,两个高速时钟关闭,电压调节器关闭,这个意味着1.8V区域的电源关闭,内部的存储器和寄存器的数据全部丢失,但是和停止模式一样,它并不会主动关闭LSI和LSE两个低速时钟,因为这两个时钟还要维持RTC和独立看门狗的运行。

接下来我们对上面内容的细节问题再额外补充和总结一下,首先是模式选择的问题,刚刚上面的表述出现了很多寄存器的位,其中这些模式,又有更细一些的划分。比如睡眠模式有SLEEP-NOW和SLEEP-ON-EXIT的区别,停机模式有电压调节器开启和低功耗的区别,我们如何配置才能指定某个模式呢?那看下面的图就能比较清晰了

最后我们再分别总结一些这三种模式的一些特性。

首先是睡眠模式:

1.执行完WFI/WFE指令后,STM32进入睡眠模式,程序暂停运行,唤醒后程序从暂停的地方继续运行。 一般我们可以在主循环的最后执行一下WFI/WFE,主循环执行一遍就睡眠,然后唤醒之后,主循环又会执行一遍再睡眠。 因为睡眠模式和停止模式下,存储器和寄存器的内容都可以维持,所以唤醒后,程序可以直接在暂停的地方继续运行。

2.SLEEPONEXIT位决定STM32执行完WFIWFE后,是立刻进入睡眠,还是等STM32从最低优先级的中断处理程序中退出时进入睡眠。

3.在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态。比如如果在程序里进行电灯,灯电亮了,再进入睡眠,灯仍然是亮的

4.WFI指令进入睡眠模式,可被任意一个NVIC响应的中断唤醒

5.WFE指令进入睡眠模式,可被唤醒事件唤醒

接下来是停止模式:

1.执行完WFI/WFE指令后,STM32进入停止模式,程序暂停运行,唤醒后程序从暂停的地方继续运行。因为睡眠模式和停止模式下,存储器和寄存器的内容都可以维持,所以唤醒后,程序可以直接在暂停的地方继续运行。

2.1.8V供电区域的所有时钟都被停止,PLLHSIHSE被禁止,SRAM和寄存器内容被保留下来

3.在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态

4.当一个中断或唤醒事件导致退出停机模式时,HSI被选为系统时钟。我们的程序,默认在SystemInit函数里的配置,是使用的HSE外部高速时钟,通过PLL倍频,得到了72MHz的主频,但是进入停止模式之后,PLL和HSE都停止了,而在退出停止模式时,它并不会再自动帮我们开启PLL和HSE,而是默认用HSI的8MHz直接作为主频。所以我们一般在停机模式唤醒后第一时间重新启动HSE,配置主频为72MHz。

5.当电压调节器处于低功耗模式下,系统从停止模式退出时,会有一段额外的启动延时

6.WFI指令进入停止模式,可被任意一个EXTI中断唤醒

7.WFE指令进入停止模式,可被任意一个EXTI事件唤醒

最后我们看一下待机模式:

1.执行完WFI/WFE指令后,STM32进入待机模式,唤醒后程序从头开始运行待机模式下唤醒,程序是从头开始运行的,因为待机模式把内部大部分电路的电源直接断了,数据都丢失了,唤醒之后程序也无法继续,只能从头开始。

2.整个1.8V供电区域被断电,PLLHSIHSE也被断电,SRAM和寄存器内容丢失,只有备份的寄存器和待机电路维持供电

3.在待机模式下,所有的I/O引脚变为高阻态(浮空输入),对于输出来说,既不输出高电平,也不输出低电平,呈现高阻态;对于输入来说,不上拉也不下拉,呈现浮空输入状态。所以说,如果提前点了灯,进入待机模式后,无论这个灯是高电平点亮还是低电平点亮,它都会熄灭。GPIO对外不输出高低电平,也不流过电流。

4.WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、IWDG复位退出待机模式。这四个是待机模式的唤醒条件。

下面进入代码部分,首先是修改主频代码。

在Start文件夹中,出了startup文件和内核的.c .h文件,还存在用于配置RCC时钟树的system文件。下图就是时钟树的全部电路,左边是4个时钟源HSI、HSE、LSE、LSI用于提供时钟,右边就是各个外设,就是使用时钟的地方,我们用的最多的就是AHB时钟、APB1时钟和APB2时钟;另外还有一些时钟,它们的来源不是AHB和APB,比如I2S的时钟,直接来源于SYSCLK,USB的时钟直接来源于PLL。我们主要关心的是这个外部的8MHz晶振,如何进行选择,如何倍频,才能得到这个72MHz的SYSCLK,系统主频,然后系统主频如何去分频,才能得到AHB、APB1和APB2的时钟频率。在我们之前的课程里,我们一直保持了默认的配置,就是晶振接的是8M,主频是72M,AHB和APB2是72M,APB1是36M,但其实这些都不是绝对的,可以根据自己的需求进行更改。在system文件中, SystemInit()函数用来配置时钟树,也是这个文件中最主要的东西,使用HSE配置主频为72M,就是这个函数干的活,并且这个函数在复位后,执行main函数之前在启动文件里自动调用了,所以main函数一进来时钟就配置好了。变量SystemCoreClock表示主频频率的值,我们想知道目前主频是多少就直接显示一下这个变量就行;函数SystemCoreClockUpdate()用来更新上面那个变量,因为这个变量只有最开始的一次赋值,之后如果我们改变了主频频率,这个值不会自动跟着变换,所以我们就需要调用一下这个函数,根据当前时钟树的配置,更新一下上面这个变量。该文件的前106行处还有更改主频宏定义的地方,我们可以解除对应的注释来选择想要的系统主频

PWR库函数中的函数介绍如下:PWR_DeInit为恢复缺省配置;PWR_BackupAccessCmd使能后备区域的访问,该函数在上一节BKP和RTC中介绍过;PWR_PVDCmd和PWR_PVDLevelConfig是跟PVD相关的函数,PWR_PVDLevelConfig就是配置可编程电压监测器(PVD)的阈值电压;PWR_PVDCmd就是使能PVD功能,如果你需要用PVD的话就先指定阈值然后Cmd使能一下即可;PWR_WakeUpPinCmd用于使能位于PA0位置的WKUP引脚,配合待机模式使用,如果你需要开启WKUP引脚唤醒功能的话,那就得调用这个函数使能一下;PWR_EnterSTOPMode函数用来进入停机模式,调用这个函数就可以进入停机模式了;PWR_EnterSTANDBYMode函数用来进入待机模式,调用这个函数就可以进入待机模式了;PWR_GetFlagStatus和PWR_ClearFlag是获取标志位和清除标志位的函数。

http://www.lryc.cn/news/608353.html

相关文章:

  • 从零打造大语言模型--处理文本数据
  • FFmpeg+javacpp中纯音频播放
  • 互联网医院系统,互联网医院好处有哪些?
  • 音视频学习(四十八):PCM和WAV
  • CatBoost 完整解析:类别特征友好的梯度提升框架
  • 基于单片机智能雨刷器/汽车刮水器设计
  • zset 中特殊的操作
  • nodejs读写文件
  • 【redis】基于工业界技术分享的内容总结
  • C++ 模板初阶
  • 阿里云:Ubuntu系统部署宝塔
  • 回归预测 | Matlab实现CNN-LSTM-self-Attention多变量回归预测
  • ventoy 是一个非常棒的开源工具,可以制作多系统的usb启动盘
  • 基于落霞归雁思维框架的软件需求管理实践指南
  • Vulnhub ELECTRICAL靶机复现(附提权)
  • 计算机技术与软件专业技术资格(水平)考试简介
  • Dispersive Loss:为生成模型引入表示学习 | 如何分析kaiming新提出的dispersive loss,对扩散模型和aigc会带来什么影响?
  • 《React+TypeScript实战:前端状态管理的安全架构与性能优化深解》
  • 【Unity3D实例-功能-移动】小兵移动-通过鼠标点击进行
  • 咨询进阶——解读57页企业发展战略咨询常用工具【附全文阅读】
  • Java Optional 类教程详解
  • C++ vector底层实现与迭代器失效问题
  • 【智能体cooragent】新智能体创建相关代码解析
  • Node.js 操作 MongoDB
  • Linux系统编程Day3-- Linux常用操作(终)
  • 2025-08 安卓开发面试拷打记录(面试题)
  • 3 使用 Jenkins 构建镜像:将你的应用打包成镜像
  • K8S部署ELK(三):部署Elasticsearch搜索引擎
  • 【机器学习】非线性分类算法(上):KNN(基于距离相似度)与朴素(特征独立)贝叶斯(基于概率统计)
  • 排序算法-堆排序