首页 > 其他分享 >STM32&低功耗与备用备份区域

STM32&低功耗与备用备份区域

时间:2024-08-14 11:24:01浏览次数:17  
标签:handle rtc RTC 备份 低功耗 STM32 time HAL void

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); 
}

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

祝你看完就会。

标签:handle,rtc,RTC,备份,低功耗,STM32,time,HAL,void
From: https://blog.csdn.net/wwwkkkxxx12138/article/details/141184410

相关文章

  • STM32&IIC与SPI详解
    单片机里的通信协议其实蛮多的,IIC;SPI;MQTT;CAN;包括串口也是一种通信协议。而串口通信虽然实现了全双工,但需要至少三根线,为了节省这一根线的成本,于是IIC诞生了。目录一.IIC协议1.IIC的结构2.IIC的特点3.IIC的通信时序4.具体配置(32HAL库版)二.SPI协议1.SPI的结构2.SPI的特......
  • 科研单位所需要的文件自动同步备份软件具有哪些特征?
    科研单位进行文件同步备份是保障数据安全、提高工作效率、符合法规要求以及实现数据共享与再利用的重要措施。文件同步备份不仅能保护科研单位的研究成果,还能提升工作协同效率,具体优势体现在:预防数据丢失:科研单位在工作中会产生大量的重要数据,包括研究成果、实验数据、专利资料等......
  • freeRTOS入门学习-基于STM32F103C8T6最小系统板-创建任务_声光色彩
    首先重温一下任务的三大要素:        ·做何事(函数)    ·栈(每个任务都应该有自己独享的栈)    ·优先级(非必要的因素,但是有了优先级可以处理更多的任务)一、如何创建任务:    当一个任务被切换出去之后,要想再找到他,应该去到某个链表里边......
  • STM32 H7系列 全中文HAL&LL库使用手册 中英双语对照 GPT机翻 共4020页、约152万字
    STM32H7系列全中文HAL_LL库使用手册,中英文双语对照阅读。内容、格式对照官方原文,含标签导航及目录跳转。全文GPT机翻,除人工翻译外,相对更加贴合原文原意,双语版防止翻译错误方便对照。全文:4020页,约152万字,2022年12月版本,当前官网最新版。 *******下有更多展示图片********......
  • [STM32]如何正确的安装和配置keil?(详细)
    一、我们为什么需要keil?    对于嵌入式开发的硬件来讲STM32可以说有着不可撼动的地位,它可能是很多人入门嵌入式开发接触到的第一款芯片,其强大的生态和大量开放的源代码也深受开发者的喜爱。对于嵌入式开发的软件来讲,keil绝对是在一届软件中脱颖而出的,它是一款集成了......
  • STM32在Keil5中DeBug界面可以正常运行但是正常运行就失败
    项目场景:提示:这里简述项目相关背景:使用STM32CubeMX建立项目生成基础代码在Keil5MDK中编写STM32F03RCT6程序问题描述提示:这里描述项目中遇到的问题:在DeBug界面可以正常运行但是一旦进行重启自启动芯片就不会正常运行在Debug运行是会卡在一下但是后续运行可继续运行......
  • 我在高职教STM32——I2C通信之读写EEPROM(3)
            大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正是如此,才有了借助CSDN平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思设计的教学课件......
  • 使用 `dd` 备份Ubuntu系统盘
    1.方案概述dd是一个低级别的数据复制工具,能够直接将磁盘或分区的内容逐位复制到另一个设备或文件中。使用dd备份系统盘可以获得整个系统的精确副本,包括操作系统、配置文件、已安装的软件、以及所有用户数据。2.前提条件源设备:包含系统的磁盘(如/dev/sda)目标设备或文件:可......
  • 【STM32】SPI通信和RTC实时时钟
    个人主页~SPI通信和RTC实时时钟SPI通信一、简介二、硬件电路三、基本原理四、SPI时序1、时序基本单元2、时序五、FLASH操作注意事项1、写入操作2、读取操作六、SPI外设1、简介2、结构七、传输方式1、主模式全双工连续传输2、非连续传输RTC实时时钟一、Unix时间戳......
  • 零基础学会制作 基于STM32/51的多功能车位锁设计/车位锁/停车计时/停车场计时器
    项目介绍本研究旨在设计并实现一款基于STM32单片机的多功能车位锁系统,该系统利用STM32单片机的高性能和低功耗特性,集成了距离检测、光照控制、蓝牙通信等多种智能技术,实现了对停车位的智能管理和自动控制。通过超声波模块实时监测车辆与车位锁之间的距离,借助光敏传感器调节......