这一节我们来学习 STM32 的 PWR 电源控制。
其中,我们重点学习的主要就是 3 种低功耗模式:睡眠模式、停机模式和待机模式。
低功耗模式的目的呢?简单明了,就是省电,这对于一些使用电池供电,又需要长时间待机的设备,十分重要。
所以我们本节课的任务,就是学习电源控制部分,看看如何配置这些低功耗模式,让 STM32 在空闲时,能够尽可能地节省电量。
好,那先看一下本节最终的程序现象。本节总共有 4 个程序,分别是 13-1 修改主频;13-2 睡眠模式+串口发送+接收;13-3 停止模式+对射式红外传感器计次;13-4 待机模式+实时时钟。因为低功耗模式的代码都不是很多,所以多给大家演示几个。
那我们先看一下第一个程序,修改主频。修改主频不属于 3 种低功耗模式,但是也是降低 STM32 功耗的一种方法,这个代码非常简单,就是初始化显示一下 SystemCoreClock
这个变量,这个变量指示了当前主频频率,之后,主循环,以 1s 为周期,显示 Running,再清除。那我们看一下程序现象,目前可以看到,第一行 SCKCLK,系统主频,是 36 MHz;第二行,我们让它以 1s 为周期显示,但现在实际上是 2s 的周期,这是因为系统主频,正常情况下是 72 MHz,现在我们降频到 36 MHz 了,所以运行时间,就是原来的 2 倍。那这就是修改主频这个程序的现象,有关这个 system 文件的详细解释,还有配置主频的更多玩法,我们写程序的时候,再来介绍。
那在这个程序的哪个部分,我修改了主频呢?答案是在 system_stm32f10x.c 文件里,system 这个文件,里面就是用来配置时钟的,在 110 行这个位置,它给我们预留好了配置时钟的宏定义,我们只需要将其中一个宏定义解除注释,就能直接配置系统的主频,非常简单。目前看到,我是把 36 M 的宏解除注释了,所以目前主频就是 36 M,这个文件在我改之前默认是 72 M,如果我们把 72 M 解除注释,把 36 M 注释掉,这样系统主频就是 72 M 了,想配置为其他的频率,也是同理,先把原来的注释掉,再解除对应频率的注释即可,是不是非常简单。
我们编译下载看一下,可以看到,目前显示主频是 72 M,Running 闪烁的周期是 1s,这是默认主频 72M 的正常现象。
如果文件图标带有钥匙标志说明此文件为只读,必须先解除只读才能修改程序,解除只读的方法为:文件夹里找到文件 -> 右键 -> 属性 ->取消只读。
接着继续看第二个程序,睡眠模式 + 串口的发送和接收,那这个程序就是从串口那一节直接复制过来的,这个代码的功能就是,当收到一个字节时,中断触发,置标志位,主循环查询到标志位时,读取数据,并用串口发送出去,在这个功能后面,我又新加了一段代码,就是用来配置睡眠模式的,关键代码实际上就一句 __WFI();
执行完这一句,芯片进入睡眠,睡眠的目的是如果 STM32 一直没收到数据,那这个主循环也会一直查询标志位,这是无意义的耗电操作,那不如我们就让它睡眠,收到数据后,自动退出睡眠模式,执行一遍任务后,继续睡眠,这样在空闲时,芯片一直在睡眠,可以降低系统功耗。那我们下载看一下程序现象,目前是串口发送加接收,我们按照串口那一节的接线接好串口,然后打开串口,随便发送一个数据,可以看到,STM32 成功接收,并回传了这个数据,这个现象和没使用睡眠模式的是一样的,但是,细节就在于,看一下第二行,只有在我们发送数据时刻,OLED 才会显示一次 Running,在空闲时,芯片一直都在睡眠,这样就是在不影响程序功能的前提下,使用睡眠模式节约电量,这就是这个程序的功能。
另外,还要重点提醒一下,芯片在 3 种低功耗模式下,是没法直接再下载程序的,你看现在是下载成功的,如果直接再点下载,就会提示报错,这是因为芯片现在在睡眠,不会理你调试端口了,解决方法也很简单,需要我们有一些操作:
- 第一步,我们按住复位键不放;
- 第二步,点下载按钮;
- 第三步,及时松开复位键。这样就能下载成功了。
在我们本节 3 种低功耗模式下,都需要这样下载程序,大家注意一下。另外,如果你不小心禁用了调试端口,其实也可以这样来解决。
接着继续看,第三个程序,停止模式 + 对射红外计次,这个程序是在之前外部中断那一节的代码基础上修改的,类似的操作,主循环中加入了 Running 的指示和最后进入停止模式的代码。那下载看一下程序现象,每遮挡一次,执行一次计次,也显示一下 Running,在没有外部中断信号时,STM32 处于停止模式,可以省电,这就是第三个程序的现象。
最后我们来看一下第四个程序,待机模式 + 实时时钟,这个程序是在实时时钟的基础上,加入了待机模式,目前这个程序,使用的是 LSE 外部低速时钟,如果你没有 RTC 晶振,或者 RTC 晶振不起振,也可以使用 LSI 内部低速时钟,LSI 在待机模式下,可以继续工作。然后在主循环中可以加入唤醒后要执行的功能,在进入待机模式之前,可以关闭各个外部连接的模块,以最大化省电,我目前是用 OLED_Clear();
模拟了一下,那这个程序,会用实时时钟设定闹钟,每隔一段时间,会自动唤醒一次,这里我演示的是,每隔 10s 唤醒一次,唤醒之后,执行一遍程序任务,随后继续待机。那看一下程序现象,复位一下,可以看到 OLED 上显示了当前时间和闹钟,随后进入待机,然后等一会闹钟触发之后,自动唤醒一次,设定新的闹钟,执行程序功能,之后继续待机,等待下一次唤醒,这就是使用 RTC 和闹钟配合待机模式的自动唤醒程序。非常适合那种,需要每隔一段时间操作一次,空闲时间又需要最大化省电的设备。
好,那程序现象,我们就看到这里。接下来看一下 PWR 的理论部分。
PWR(Power Control,电源控制)
PWR 就是 Power 的缩写。
PWR 的作用:PWR 负责管理 STM32 内部的电源供电部分,可以实现 可编程电压监测器 和 低功耗模式 的功能。
PWR 有一部分是硬件的介绍,就是告诉你,内部供电电路的结构是啥样的,这些是设计硬件电路时要考虑的,暂时不涉及程序。涉及程序的功能,主要就是两个,一个是可编程电压监测器,另一个是低功耗模式。
可编程电压监测器(PVD)可以监控VDD电源电压,当 VDD 下降到 PVD 阀值以下或上升到 PVD 阀值之上时,PVD 会触发中断,用于执行紧急关闭任务。
这个功能预想的场景应该是,使用电池供电,或者对安全要求比较高的设备,如果供电电压在逐渐下降,在电压过低的情况下,可能会导致内部或者外部电路发送不确定的错误,为了避免不确定的因素,在电源电压低于设定的阈值时,我们可以主动出击,提前发出警告,并且关闭比较危险的设备,这是 PVD 的设计。不过 PVD 这个功能不是我们本节课的重点,我们暂时也不演示代码,大家了解即可,后续需要的话可以再研究。
低功耗模式* 包括睡眠模式(Sleep)、停机模式(Stop)和待机模式(Standby),作用就是:可在系统空闲时,降低STM32的功耗,延长设备使用时间。尤其是像一些用电池供电的设备,对空闲时候的耗电量是有极大要求的,比如数据采集设备,车钥匙,遥控器,报警器等等。
这些产品都有特点,就是在它们的生命周期里,绝大部分时间,都是空闲状态。但是我们知道,单片机程序一旦开始,正常运行的状态下,程序永远都不会停下来,所以主程序的最后,一般都是个死循环,即使需要空闲,让程序停下来,那也得来个空循环让程序一直转圈卡住。但是,程序运行就会耗电,空循环的耗电量也是很大的,比如遥控器,如果不用它的时候,程序一直空循环,那么用不到几天,电池就没电了,这显然是不行的。
所以说对于这些设备,我们需要这样的低功耗模式,在空闲状态时,关闭不必要的硬件,比如我直接把 CPU 断电,或者关闭时钟,这样程序自然就不会运行了。但是在低功耗模式下,我们也需要保留必要的唤醒电路,比如串口接收数据的中断唤醒、外部中断唤醒、RTC 闹钟唤醒,等等,在需要设备工作时,STM32 能够立刻重新投入工作,这样才行,如果你只考虑进入低功耗而不考虑唤醒,STM32 一睡不醒,那不就跟直接断电没区别了嘛。所以,低功耗模式,我们要考虑关闭哪些硬件,保留哪些硬件,以及如何去唤醒,当然关闭越多的硬件,设备越省电,唤醒就越麻烦,这也是这 3 种低功耗模式在设计时,所区分的地方。
这是本节的重点内容。英文大概记一下,前面两个应该都很熟悉,主要记一下 Standby,表示待机模式,这个在很多其他芯片里,都有出现。
那简介就看到这里,接着我们看一下电源框图。
这个图就是 STM32 内部的供电方案。其中有些部分我们之前也已经了解过,现在再来看看。整体上看,这个图可以分为 3 个部分。
最上面是模拟供电,叫做 VDDA(VDD Analog)。VDDA 供电区域,主要负责模拟部分的供电,其中包括 AD 转换器、温度传感器、复位模块、PLL 锁相环,这些电路的供电正极是 VDDA,负极是 VSSA。其中 AD 转换器还有两根参考电压的供电脚,叫做 VREF+ 和 VREF-,这两个脚在引脚多的型号里会单独引出来。在引脚少的型号,比如我们这个 C8T6,VREF+ 和 VREF- 在内部就已经分别接到了 VDDA 和 VSSA 了。
中间是数字部分供电,包括两块区域,VDD 供电区域和 1.8V 供电区域。左边部分是 VDD 供电区域,其中包括 IO 电路、待机电路、唤醒逻辑和独立看门狗;右边部分是 VDD 通过电压调节器,降压到 1.8V,提供给后面这一块的 1.8V 供电区域,1.8V 区域包括 CPU 核心、存储器和内置数字外设。可以看出,STM32 内部的大部分关键电路,CPU、存储器和外设,其实都是以 1.8V 的低电压运行的,当这些外设需要与外界进行交流时,才会通过 IO 电路转换到 3.3V;所以我们从外部看好像 STM32 内部全是 3.3V,但实际上它内部的 CPU、外设等,都是以 1.8V 供电运行,使用低电压运行的主要目的是降低功耗,电压越低,内部电路运行的功耗就相对越低。
当然我们其实也不用了解这么多,主要是记住,CPU 核心、存储器和数字外设,都属于 1.8V 供电区域;而待机电路,唤醒逻辑等,属于 VDD 供电区域,它们的位置要清楚。然后电压调节器它的作用是给 1.8V 区域供电,因为后面我们会提到这个 1.8V 区域和电压调节器,你要知道是啥。
下面是后备供电,叫做 VBAT(V Battery)。VBAT 后备供电区域其中包括 LSE 32K 晶体振荡器、后备寄存器、RCC BDCR 寄存器和 RTC。RTC BDCR 是 RCC 的寄存器,叫备份域控制寄存器,也是和后备区域有关的寄存器,所以也可以由 VBAT 供电。然后上面有个低电压检测器,可以控制开关,VDD 有电时,由 VDD 供电;VDD 没电时,由 VBAT 供电。
好,那这些就是电源框图的介绍了。大家需要了解的是,STM32 内部有哪几部分供电区域,以及每部分供电区域里都有啥,这就是这个框图的内容。
然后继续看下两个图,分别是上电复位和掉电复位还有可编程电压监测器。这两个内容了解即可,快速介绍一下。
首先是上电复位和掉电复位。这个的意思是,当 VDD 或者 VDDA 电压过低时,内部电路直接产生复位,让 STM32 复位住,不要乱操作,这个复位和不复位的界限之间,设置了一个 40 mV 迟滞电压,大于上限 POR(Power On Reset)时解除复位,小于下限 PDR(Power Down Reset)时复位。这是一个典型的迟滞比较器,设置两个阈值的作用,就是防止电压在某个阈值附近波动时,造成输出也来回抖动。下面的复位信号 Reset,是低电平有效的,所以在前面和后面,电压过低时,是复位的,中间电压正常的时候,不复位。
那这个电压上限和下限,具体是多少 V 呢,还有这里解除复位,还有个滞后时间,是多久呢,这些参数,可以看一下 STM32 数据手册,在 5.3.3 内嵌复位和电源控制模块特性里有个表,这里写了上电或掉电复位阈值,下降沿,也就是 PDR 掉电复位的阈值下限,典型值是 1.88V;上升沿,也就是 PDR 上电复位的阈值上限,典型值是 1.92V;1.92 - 1.88 V 就是迟滞的阈值,40 mV,所以如果忽略迟滞的话,简单来说,就是大于 1.9V 上电,低于 1.9V 掉电。然后最后一行,就是 TRSTTEMPO 复位持续时间,典型值是 2.5 ms,这就是这个上电复位和掉电复位。知道一下就行,也不需要我们操作啥的。
然后下面这个是可编程电压监测器,简称 PVD。