STM32单片机学习(37) —— PWR和BKP

文章目录

写在前面

这一篇内容包括两个内容,一个是PWR电源控制以及BKP备份寄存器。因为BKP的内容不多所以就合并到一起了。另外就是我与大家分享一个关于我的小插曲。在这最后我们同样还是会有个关于低功耗的小实验。原本我是不打算写在这里的。等我们学完之后就会知道stm32f103c8t6的芯片唤醒低功耗模式会有一些局限性。所以我上网查了有专门应对低功耗场景的芯片L0系列。这个芯片有一个LPUART,就是说他可以通过USART通信唤醒STOP模式(这些下面都会讲到)。但是我买来之后,发现官网没有相关SPL库,后来才知道,它只支持HAL库开发,博主尚未涉猎HAL库,所以只能放弃。然后看到官网有L1系列的SPL库,然后又买了stm32L151c8t6。当我建好工程项目的时候,发现L1系列的也不支持LPUART,唤醒手段和f103一样,只是主频低了。所以,最后还是选择用经典的f103c8t6作为此次的开发环境。

电源

STM32的工作电压(VDD)为2.0~3.6V。通过内置的电压调节器提供所需的1.8V电源。

当主电源VDD掉电后,通过VBAT脚为实时时钟(RTC)和备份寄存器提供电源。

解读一下上面的电源图示,详细内容还是参考官方的参考手册

  • ADC使用了独立的电源供电

    可以在最上面可以看到 V D D A V_{DDA} VDDA供电区域中的A/D转换器,这是为了过滤和屏蔽来自印刷电路板上的毛刺干扰,另外复位模块我们不难理解。关于温度传感器和PLL(锁相环,用来对时钟进行倍频)。同样也是保证系统稳定运行的

  • 中间部分

    也就是MCU正常工作的地方由 V D D V_{DD} VDD同一进行供电

  • V B A T V_{BAT} VBAT部分

    这就是我们后面要讲到的BKP部分,在我们的电路板上右上角有个引脚VBT就是这个,接入可以保证部分数据不丢失,但是保护的数据也十分有限。可以存储类似时间戳一类的数据,那么即使断电,我们的时间依然是准确的。

电压调节器

复位后调节器总是使能的。根据应用方式它以3种不同的模式工作。

  • 运转模式:调节器以正常功耗模式提供1.8V电源(内核,内存和外设)。
  • 停止模式:调节器以低功耗模式提供1.8V电源,以保存寄存器和SRAM的内容。
  • 待机模式:调节器停止供电。除了备用电路和备份域外,寄存器和SRAM的内容全部丢失。

电源管理器

上电复位(POR)和掉电复位(PDR)

STM32内部有一个完整的上电复位(POR)和掉电复位(PDR)电路,当供电电压达到2V时系统既能正常工作。当VDD/VDDA低于指定的限位电压VPOR/VPDR时,系统保持为复位状态,而无需外部复位电路。关于上电复位和掉电复位的细节请参考数据手册的电气特性部分。

可编程电压检测器(PVD)

用户可以利用PVD对VDD电压与电源控制寄存器(PWR_CR)中的PLS2:0位进行比较来监控电源,这几位选择监控电压的阀值。通过设置PVDE位来使能PVD。电源控制/状态寄存器(PWR_CSR)中的PVDO标志用来表明VDD是高于还是低于PVD的电压阀值。该事件在内部连接到外部中断的第16线,如果该中断在外部中断寄存器中是使能的,该事件就会产生中断。当VDD下降到PVD阀值以下和(或)当VDD上升到PVD阀值之上时,根据外部中断第16线的上升/下降边沿触发设置,就会产生PVD中断。例如,这一特性可用于用于执行紧急关闭任务。

可以看到这两张图的电压都有两个阈值。这是为了防电压不稳定时在阈值附近波动

低功耗模式

在stm32f103c8t6中PWR中我们可以设置三种低功耗模式:

  • SLEEP模式(内核和停止,所有外设包括Cortex-M3核心的外设继续工作)
  • STOP模式(所有时钟停止)
  • STANDBY模式(1.8V电源关闭)

除了提供给我们的三种低功耗模式,我们也可以自己通过设置系统参数来降低功耗

  1. 降低时钟频率


    从这里我们可以看到,可以通过修改这里的宏来进行主频的配置,但是一般不建议修改,如果你修改了这里,你的程序逻辑也要相应的修改,比如延时1s,你如果改成36000000,那可能就是延时两秒。总的来讲,修改了系统主频,就是修改了系统的反应时间,所以相应的程序处理逻辑也要进行修改。

  2. 关闭APB和AHB总线上未被使用的外设时钟

    这一点很好理解,其实就是你用的越少就越省电,空转肯定比用很多外设省电。但实际上就算程序空转也是十分耗电的。所以我们还是合理规划外设的使用情况下通过MCU提供给我们的低功耗方式

这三种模式的进入和唤醒,从代码上来讲是非常简单的。

睡眠模式(SLEEP)就是CPU停止工作,外设和时钟都在继续工作,所以只是一定程度上节省开销,但是总要好过修改主频的方式

停机模式(STOP)可以理解为保留了当前MCU所有程序运行的快照,当被唤醒时,可以继续之前的工作。

待机模式(STANDBY)这是最低功耗,只会保留备份寄存器的内容其他都会清空。如果在该模式唤醒,你会发现你的程序是从头执行的。

在这里就可以提到我开头的小插曲了

可以看到只有SLEEP模式是任一中断唤醒的,其他两种需要外部中断唤醒。在之前我们学习了DMA+IDLE接收数据的方式,本质上它节省了CPU的开销,也是降低了功耗,但是CPU仍然是在工作的,实际的耗电情况并没有明显改变。如果我们可以使用STOP模式让MCU深度睡眠。当有指令来的时候,再执行命令,这样可以极大的降低功耗。一个典型的例子就是我们的汽车钥匙或是遥控器。如果说在我们不使用的情况下它依然在空转那么很快就会没电了。但是如果采用低功耗就不一样了。

这是来自AI的例子:

为了让你直观地感受到STM32不同功耗模式下的能耗差别,我们以一个**"智能温湿度传感器"**(由一颗纽扣电池供电)为例。

假设这个传感器每隔一段时间需要唤醒,读取一次温湿度数据,然后通过串口发送给主机。在两次读取数据的漫长间隔中,它处于空闲状态。

以下是它在四种模式下的真实表现:

1. 运行模式(Run Mode)------ "全速行驶的燃油车"

  • 状态:CPU全速运行,所有外设(ADC、串口等)都在工作。
  • 能耗表现 :电流消耗在 mA(毫安)级别(例如 35mA)。
  • 现实结果 :如果传感器一直在这个模式下"空转"等待下一次测量,一颗普通的纽扣电池(约220mAh)可能在 几个小时甚至几天内 就会被耗尽。

2. 睡眠模式(Sleep Mode)------ "汽车等红灯(怠速状态)"

  • 状态:CPU(内核)停止工作,但定时器、ADC等外设还在继续运行。
  • 能耗表现 :电流依然在 mA级别(例如 2~5mA)。
  • 现实结果 :虽然CPU不干活了,但外设还在耗电。电池依然撑不过 几天。这种模式只适合极短时间的空闲。

3. 停止模式(Stop Mode)------ "汽车熄火但保留了行车电脑记忆"

  • 状态:所有高速时钟关闭,但RAM和寄存器的数据被完整保留。
  • 能耗表现 :电流骤降至 μA(微安)级别(例如 10~20μA)。
  • 现实结果 :能耗比运行模式降低了成百上千倍。传感器在休眠时几乎不耗电,只有当RTC定时器报警或外部按键触发时才会醒来。在这种模式下,一颗纽扣电池可以支撑设备连续工作 几个月甚至大半年

4. 待机模式(Standby Mode)------ "汽车彻底断电,拔掉电瓶"

  • 状态:1.2V核心电源完全关闭,RAM里的数据全部丢失。
  • 能耗表现 :达到极致,电流低至 1μA以下(例如 0.29μA)。
  • 现实结果 :设备进入了深度休眠。唤醒后,单片机相当于重新上电复位,必须从头开始执行代码。在这种模式下,一颗纽扣电池足以让传感器在野外连续工作 一到两年

低功耗模式下的自动唤醒(AWU)

RTC可以在不需要依赖外部中断的情况下唤醒低功耗模式下的微控制器(自动唤醒模式)。RTC提供一个可编程的时间基数,用于周期性从停止或待机模式下唤醒。通过对备份区域控制寄存器(RCC_BDCR)的RTCSEL1:0位的编程,三个RTC时钟源中的二个时钟源可以选作实现此功能。

  • 低功耗32.768kHz外部晶振(LSE) :该时钟源提供了一个低功耗且精确的时间基准。(在典型情形下消耗小于1µA)
  • 低功耗内部RC振荡器(LSI RC) :使用该时钟源,节省了一个32.768kHz晶振的成本。但是RC振荡器将少许增加电源消耗。

为了用RTC闹钟事件将系统从停止模式下唤醒,必须进行如下操作:

  • 配置外部中断线17为上升沿触发。
  • 配置RTC使其可产生RTC闹钟事件。

如果要从待机模式中唤醒,不必配置外部中断线17。

因为RTC的时钟源可由VBAT单独供电,所以它不依靠其他已经被关闭的时钟源,则可以实现唤醒操作

备份寄存器(BKP)

简介

备份寄存器是42个16位的寄存器,可用来存储84个字节的用户应用程序数据。他们处在备份域里,当VDD电源被切断,他们仍然由VBAT维持供电。当系统在待机模式下被唤醒,或系统复位或电源复位时,他们也不会被复位。此外,BKP控制寄存器用来管理侵入检测和RTC校准功能。复位后,对备份寄存器和RTC的访问被禁止,并且备份域被保护以防止可能存在的意外的写操作。执行以下操作可以使能对备份寄存器和RTC的访问。

  • 通过设置寄存器RCC_APB1ENR的PWREN和BKPEN位来打开电源和后备接口的时钟
  • 电源控制寄存器(PWR_CR)的DBP位来使能对后备寄存器和RTC的访问。

BKP特性

  • stm32f103c8t6中有10后备寄存器(每个寄存器2字节)

  • 用来管理防入侵检测并且具有中断功能的状态/控制寄存器

    防入侵检测类似于一个保险箱,你拔掉了电源可以不用输入密码打开,但是设置了一个小开关,你打开会碰到,这个小开关是独立供电的不受影响,碰到之后就自毁。大概是这么个意思

    比如你的产品里边,在BKP中存了一些核心的数据,那么有人想拆开连接你的芯片研究一下,拆开的那一瞬间,就可以触发,然后清空寄存器数据。

    这里就是我的理解,详细内容可以查看手册

RTC校准

为方便测量,RTC时钟可以经64分频输出到侵入检测引脚TAMPER上。通过设置RTC校验寄存器(BKP_RTCCR)的CCO位来开启这一功能。通过配置CAL6:0位,此时钟可以最多减慢121ppm。关于RTC校准和如何提高精度,请看AN2604"STM32F101xx和STM32F103xx的RTC校准

实验

这篇实验我们可以结合上一个打印日期的实验结合起来。我们可以让MCU处于低功耗的模式,如果使用SLEEP模式我们可以通过USART,如果是STOP或STANDBY模式可以设置一个按键来触发外部中断。触发一次打印一次时间,这里的时间是不受影响的,因为RTC是独立供电的。或者也可以尝试使用闹钟。然后街上VBAT,每次唤醒都存储当前时间戳,这样即使断电,时间依然是准确的。

(另外这里要说明一下,如果你使用杜邦线直接接到3.3V,你是不能拔地线的,因为没有给他独立接地线,说白了就是只有正极没有负极,不要测试的时候一股脑都拔了)

在这个实验中可以把三种模式都试一下,代码不难,我就只简单演示一下sleep模式.代码都是沿用的前篇代码,只是需要一个__WFI();

c 复制代码
#include "stm32f10x.h"
#include "Delay.h"
#include "../RTC.h"
#include "USART1.h"
#include <time.h>

extern volatile uint8_t flag;

int main(){
	init_USART1();
	init_RTC();
	init_NVIC();
	time_t tim;
	while(1){
		USART1_SendStr("wake up!\n");
		if(flag){
			tim = RTC_GetCounter() + 8 * 60 * 60; // 默认是伦敦时间,转换成北京时间要加8小时
			USART1_SendStr(asctime(localtime(&tim)));
			flag = 0;
		}
		
		__WFI();
	}
}

可以看到如果没有休眠的话应该疯狂打印wake up。说明进入了休眠模式。我是使用的IDLE中断,所以输入任意字符会唤醒一次打印时间

相关推荐
万岳科技1 小时前
教育培训系统开发流程详解:平台建设关键环节解析
数据库·后端·学习
fanged1 小时前
高通学习14--RB5(TODO)
学习
牛牛,牛1 小时前
榨干最后一微安:STM32 的低功耗设计与中断唤醒机制深度剖析
单片机·嵌入式硬件
星华云2 小时前
[STM32] SAR型ADC(逐次逼近型ADC)工作原理简介
stm32·单片机·嵌入式硬件
小娄~~2 小时前
时钟控制器原理
单片机·嵌入式硬件
Tbisnic3 小时前
AI大模型学习第十四天:Coze项目实战中的分治智慧
人工智能·python·学习·大模型·工作流·智能体·coze
小风吹啊吹~3 小时前
通过时态图学习意图驱动识别足球控球比赛阶段 论文详解
学习·transformer·论文笔记·gan·足球战术·战术分析系统
阿i索3 小时前
【C++学习笔记】【基础】4.string类(2)——模拟实现
c++·笔记·学习