STM32低功耗与备用备份区域

news2024/12/27 16:07:31

STM的备份备用区域其实就是两个区块:BKP和RTC。低功耗则其实是STM32四种模式中的三种耗能很低的模式。

目录

一:备用区域

1.BKP

2.RTC

二:低功耗模式

1.睡眠模式:

2.停机模式:

3.待机模式:


一:备用区域

1.BKP

BKP就是一个备份寄存器,大小不是一定的。但基本单位都是16位。所谓的的备份,其实在这里的意义就是当主要供电丧失后不会丢失数据。在板子上的体现就是:复位后数据不丢失。

当然了,你要是直接给你板子电源拔了它该丢失还是丢失的。

这个区域没什么好讲的,就是简单的读写。要记住的东西就是:
1.备用供电时Vbat
2.复位后不能直接访问,需要打开时钟:
通过设置寄存器RCC_APB1ENR的PWREN和BKPEN位来打开电源和后备接口的时钟

3.其内部有校准RTC的寄存器。

代码部分:

#include "bkp.h"

RTC_HandleTypeDef rtc_handle = {0};
void RTC_INIT(){
	__HAL_RCC_BKP_CLK_ENABLE();		//使能后背域时钟
	__HAL_RCC_PWR_CLK_ENABLE();		//使能电源时钟	
	HAL_PWR_EnableBkUpAccess();		//使能后背域访问
	
	
	/*rtc_handle.Instance = RTC;	
	rtc_handle.Init.AsynchPrediv = 32767;	//时钟源的HZ为323768,为了将RTC配置为1HZ,所以溢出值设定为32767
	HAL_RTC_Init(&rtc_handle);*/
}

uint16_t RTC_read_data(uint8_t bkpx){
	uint32_t data_read;
	data_read = HAL_RTCEx_BKUPRead(&rtc_handle,bkpx);
	return data_read;
}

void RTC_write_data(uint8_t bkpx,uint32_t data_write){
	HAL_RTCEx_BKUPWrite(&rtc_handle,bkpx,data_write);
}

没什么难点就是一些API直接的调用。

2.RTC

RTC本质上是一个独立的定时器。所谓独立,其实就是复位后它数据可以保存,但是注意,这里它的属于来源其实是BKP。前面讲过BKP中有RTC的校准器,所以如果你希望在复位后RTC的数值保持不丧失你最好先初始化BKP。

RTC框图

图中红框内就是这个模块的重点。
初始化的过程也和重点对应:
 RTCCLK选择振荡器HAL_RCC_OscConfig HAL_RCCEx_PeriphCLKConfig
                                        |
 RTC分频器选择分频数rtc_handle.Init.AsynchPrediv = 32767;
                                        |
        CNT的赋值HAL_RTC_SetTime HAL_RTC_SetDate
代码:

 

#include "rtc.h"
#include "uart1.h"
RTC_HandleTypeDef rtc_handle = {0};
void RTC_INIT(void){
	__HAL_RCC_BKP_CLK_ENABLE();		//使能后背域时钟
	__HAL_RCC_PWR_CLK_ENABLE();		//使能电源时钟	
	HAL_PWR_EnableBkUpAccess();		//使能后背域访问
	
	rtc_handle.Instance = RTC;	
	rtc_handle.Init.AsynchPrediv = 32767;	//时钟源的HZ为323768,为了将RTC配置为1HZ,所以溢出值设定为32767
	HAL_RTC_Init(&rtc_handle);
}
void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc){
	//配置振荡器时钟
	RCC_OscInitTypeDef  rcc_osc = {0};
	rcc_osc.PLL.PLLState = RCC_PLL_NONE;
	rcc_osc.LSEState = RCC_LSE_ON;
	rcc_osc.OscillatorType = RCC_OSCILLATORTYPE_LSE;
	
	//选择振荡器时钟
	RCC_PeriphCLKInitTypeDef  perh_init = {0};
	perh_init.PeriphClockSelection = RCC_PERIPHCLK_RTC;		//外设确认
    perh_init.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;		//时钟确认
	
	HAL_RCC_OscConfig(&rcc_osc);
	HAL_RCCEx_PeriphCLKConfig(&perh_init);
}
void Read_RTC_time(void){
	RTC_TimeTypeDef time_handle = {0};
	RTC_DateTypeDef date_handle = {0};
	HAL_RTC_GetTime(&rtc_handle,&time_handle,RTC_FORMAT_BIN);	//最后一位是时间格式	
	HAL_RTC_GetDate(&rtc_handle,&date_handle,RTC_FORMAT_BIN);
	
	printf("Get time : %d-%02d-%02d-%02d-%02d-%02d \r\n",
	date_handle.Year + 2000,date_handle.Month,date_handle.Date,time_handle.Hours,time_handle.Minutes,time_handle.Seconds);	
}

void Set_RTC_time(struct tm time_struct){
	RTC_TimeTypeDef time_handle = {0};
	RTC_DateTypeDef date_handle = {0};
	
	date_handle.Year = time_struct.tm_year - 2000;
	date_handle.Month = time_struct.tm_mon;
	date_handle.Date = time_struct.tm_mday;
	
	time_handle.Hours = time_struct.tm_hour;
    time_handle.Minutes = time_struct.tm_min;
    time_handle.Seconds = time_struct.tm_sec;
	
	HAL_RTC_SetTime(&rtc_handle,&time_handle,RTC_FORMAT_BIN);
	HAL_RTC_SetDate(&rtc_handle,&date_handle,RTC_FORMAT_BIN);
	
	while(!__HAL_RTC_ALARM_GET_FLAG(&rtc_handle,RTC_FLAG_RTOFF));	//确定写入完成后在继续

}

其实看着华丽呼哨的都是在赋值。RTC内部的时钟生成的是一个时间戳。你知道的,时间赋值就是很麻烦。简而言之这里是吧时间分为DATE和TIME两部分赋值。调用了是个time.h的库搞了一个结构体吧数值赋值进去。就这么简单。

RTC还有闹钟功能,总体的流程也是非常经典:
在上面的基础上 配置NVIC 设定闹钟(使能中断允许位)配置中断回调函数

    HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 2, 2);
    HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
}
void RTC_Alarm_IRQHandler(void)
{
    HAL_RTC_AlarmIRQHandler(&rtc_handle);
}
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
    printf("ring ring ring...\r\n");
}
void rtc_set_alarm(struct tm alarm_data)
{
    RTC_AlarmTypeDef alarm = {0};
    
    alarm.Alarm = RTC_ALARM_A;
    alarm.AlarmTime.Hours = alarm_data.tm_hour;
    alarm.AlarmTime.Minutes = alarm_data.tm_min;
    alarm.AlarmTime.Seconds = alarm_data.tm_sec;
    HAL_RTC_SetAlarm_IT(&rtc_handle, &alarm, RTC_FORMAT_BIN);
}

多余的配置代码我就不给了因为都一样。

二:低功耗模式

STM32一共有四种模式:运行模式;睡眠模式;停机模式;待机模式;这四个模式这里按照省电效率依次排列,待机模式最省电。我们平常上电时默认则是运行模式/。

就不分开讲了吧,因为非常的相似,这里给一个手册里的图吧:

这里只说一点,为了方面切换模式且一个方法能唤醒任何一种模式;我们在睡眠模式选择WFI的进入方式,然后配置一个WKUP的引脚位上升沿的中断触发。 

1.睡眠模式:

本质上睡眠模式就是把CPU关了外设没关。所有的GPIO口和其他外设都保持工作。
这里的WFI和WIE其实是 wait for interrupt 和wait for evnt;那就理解了唤醒方式为什么不同了。

唯一要注意一点:在进入模式前最好关闭Systick。

2.停机模式:

跟睡眠模式的区别就是外设不工作了,同时CPU也不工作了,唯一保持的就是CPU部分的供电

这里一样也要在进入模式前关闭Systick;并选择WFI进入。

3.待机模式:

这个模式就比较特别了:
如果把前两个模式都比作放假的话,那么这个模式就是“停业整顿”;当进入待机模式时,所有外设包括CPU全部停止工作。唯一不留下的就是我们前边配置的WKUP引脚用于唤醒。

另外要注意:它的唤醒标志最好在进入前清零。并且,在进入待机模式后再出来时,系统的主频率会从72M变为8M,所以必须重新初始化时钟树

代码:
 

#include "lwr.h"

void LWR_INIT(){
	//初始化WUK针脚
	GPIO_InitTypeDef gpio_init;
	
	gpio_init.Mode = GPIO_MODE_IT_RISING;
	gpio_init.Pin = GPIO_PIN_0;
	gpio_init.Pull = GPIO_PULLUP;
	gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
	
	__HAL_RCC_GPIOA_CLK_ENABLE();
	HAL_GPIO_Init(GPIOA, &gpio_init);

	HAL_NVIC_EnableIRQ(EXTI0_IRQn);
	HAL_NVIC_SetPriority(EXTI0_IRQn,2,2);

}

void EXTI0_IRQHandler(){
	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

void Sleep_mode(){
	//停止滴答定时器
	HAL_SuspendTick();
	HAL_PWR_EnterSLEEPMode(1,PWR_SLEEPENTRY_WFI);
}

void Stop_mode(){
	HAL_SuspendTick();
	HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
}

void StandBy_mode(){
	//使能电源控制时钟(关闭电压调节器)
	__HAL_RCC_PWR_CLK_ENABLE();
	//使能一个唤醒引脚
	HAL_PWR_EnableWakeUpPin(GPIO_PIN_0);
	//复位唤醒标志位
	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
	HAL_PWR_EnterSTANDBYMode();
	//当从待机模式返回时主时钟会从72M变为8M所以要重新初始化
	stm32_clock_init(RCC_PLL_MUL9); 
}

注意:虽然这里的中断只是为了唤醒系统而不做任何操作,但也必须完整写下来。

祝你看完就会。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2040992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI绘画赏析:基于Stable Diffusion扩散模型

**Stable Diffusion**是2022年发布的深度学习文本到图像生成模型。它主要用于根据文本的描述产生详细图像,尽管它也可以应用于其他任务,如内补绘制、外补绘制,以及在提示词指导下产生图生图的翻译。它是一种潜在扩散模型,由慕尼黑…

【网络安全】15种常见网络攻击类型及防御措施_请列举至少三种常见的网络攻击类型,并说明如何通过防火墙、入侵检测系统等工具来

随着攻击者效率和复杂性的提高,网络犯罪每年都在急剧增加。网络攻击的发生有多种不同的原因和多种不同的方式。但是,一个共同点是网络犯罪分子会寻求利用组织的安全策略、实践或技术中的漏洞。 什么是网络攻击? 网络攻击是指攻击者出于盗窃…

防火墙入侵防御实验

一、实验目的及拓扑 实验目的:在防火墙上配置入侵防御(跨站脚本攻击)策略并在安全策略应用,通过虚拟机访问进行验证 二、基本配置 1、如图所示配置接口地址(省略) 2、配置区域接口 [FW1]dis zone loca…

文字翻译工具软件哪个好?这5款翻译神器好用到犯规

在日常工作和学习中,遇到需要翻译文字的情况再所难免。无论是查阅外文文献、与国际友人交流,还是理解不同语言的资讯,一款好用的文字翻译工具app都能大大提升我们的效率。 今天,我将给大家安利5款超实用的文字翻译工具app &#…

运维工程师必备技能:nc命令详解

🍁博主简介: 🏅云计算领域优质创作者 🏅2022年CSDN新星计划python赛道第一名 ​ 🏅2022年CSDN原力计划优质作者 ​ 🏅阿里云ACE认证高级工程师 ​ 🏅阿里云开发者社区专家博主 💊交流…

Java超市收银系统(七、商品修改和删除)

引言 当选择1时,显示 “输入商品编码:”,输入商品表中条码,若条码存在则删除商品表中的数据信息;若条码不存在,则显示 “你输入的编码不存在,请重新输入”。当选择2时,显示 “输入商…

【等保测评】Mysql测评中使用的命令汇总

一、身份鉴别 a) 应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换; mysql -uroot -p 查看登录是否需要输入口令鉴别用户身份 select user,host from mysql.user 查看是否存在相同账户…

OpenCV图像滤波(17)计算图像梯度函数Sobel()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 Sobel()函数用于计算图像的一阶、二阶、三阶或混合导数。它使用扩展的Sobel算子来执行这一任务。 在所有情况下,除了一种情况之外&am…

微信小程序 ==== 半屏打开小程序

目录 打开半屏小程序 调用流程 打开半屏小程序 半屏小程序环境判断 返回原小程序 使用限制 wx.openEmbeddedMiniProgram 功能描述 参数 wx.navigateBackMiniProgram 功能描述 示例代码 Object wx.getEnterOptionsSync() 功能描述 返回值 返回有效 referrerInfo…

数据可视化之旅,从数据洞察到图表呈现,可视化的产品设计

图表作为数据可视化的重要工具,是对原始数据进行深度加工与解读的有效手段,它助力我们洞悉数据背后的真相,使我们能更好地适应这个由数据驱动的世界。无论是工作汇报、项目实施、产品设计、后台界面还是数据大屏展示,图表都扮演着…

Transformer目标检测 | DETR论文解读

0. 前言 DETR是首个将Transformer应用到2D目标检测任务中的算法,由Facebook于2020年在论文《End-to-End Object Detection with Transformers》中提出。与传统目标检测算法不同的是,DETR将目标检测任务视为一个直接的集合预测问题,采用基于集…

Java同城宠物兼职遛狗系统小程序源码

🐾【同城新宠】遛狗兼职大揭秘!一键解锁“遛狗系统”,狗狗开心你也赚!✨ 🐾 开篇:告别孤单,狗狗也需要社交圈!👭 Hey小伙伴们,你家的小毛球是不是总在家里闷…

周杰伦又救了腾讯音乐一次

文丨郭梦仪 “一个周杰伦撑起了半个腾讯音乐”,近十年前对腾讯音乐的调侃,如今依然成立。 作为中国乐坛霸主,腾讯音乐(简称TME,1698.HK)过去打下的音乐版权江山,似乎已成其取之不尽的金矿&…

Github-vscode联合使用保姆及教程

Github-VScode联合使用保姆及教程 update: 2024/8/10 _Karen bluu 文章目录 Github-VScode联合使用保姆及教程1.Git 和 Github分别是什么2.安装2.1 git安装2.2 vscode安装 3. 使用Github3.1 拉取项目3.1.1 拉取方法3.1.2 注意事项 3.2 寻找合适的项目3.3 创建自己的github仓库3…

【Python学习-UI界面】PyQt5 小部件12-QStackedWidget 多页显示

功能和 QTabWidget 类似,它也有助于高效利用窗口的客户区域。 QStackedWidget 提供了一个窗口堆栈,每次只能查看一个窗口。它是建立在 QStackedLayout 之上的一个有用的布局。 样式如下: 右键可以变型为QTabWidget

养生生活视频素材去哪里找?养生系列视频素材网站分享

如何寻找高质量的养生视频素材。无论您是刚入行的新手,还是拥有众多粉丝的资深创作者,优质的养生视频素材都是吸引观众的关键。接下来,我将介绍一些顶级平台,帮助您轻松获取各类养生视频素材。 蛙学网 首先推荐的平台是蛙学网。这…

redisssion分布式锁

分布式锁的问题 基于setnx的分布式锁实现起来并不复杂,不过却存在一些问题。 锁误删问题 第一个问题就是锁误删问题,目前释放锁的操作是基于DEL,但是在极端情况下会出现问题。 例如,有线程1获取锁成功,并且执行完任…

Vue2 和 Vue3中EventBus使用差异

目录 前言一、EventBus 和 mitt 的对比二、Vue 2 中的 EventBus 使用实例2.1 创建 EventBus2.2 在组件中使用 EventBus2.2.1 组件 A - 发送事件2.2.2 组件 B - 监听事件 2.3 注意事项 三、Vue 3 中的 mitt 使用实例3.1 安装 mitt3.2 创建 mitt 实例3.3 在组件中使用 mitt3.3.1 …

【笔记】MSPM0G3507开发环境搭建——MSPM0G3507与RT_Thread(一)

环境搭建大体过程就不再赘述了,本文记录一下我刚开始搭建环境时踩过的坑以及一些不太懂的地方。后边会出MSPM0G3507RT-Thread 3.1.5相关的教程,感兴趣记得点点关注。 本篇使用立创地猛星MSPM0G3507开发板 参考文章: 【学习笔记一】搭建MSPM…

几种Word Embedding技术详解

NLP 中的词嵌入是一个重要术语,用于以实值向量的形式表示用于文本分析的单词。这是 NLP 的一项进步,提高了计算机更好地理解基于文本的内容的能力。它被认为是深度学习在解决具有挑战性的自然语言处理问题方面最重要的突破之一。 在这种方法中&#xff…