一个人可以建设几个网站,家具设计大师,云服务器怎么用,网页升级访问更新狼STM的备份备用区域其实就是两个区块#xff1a;BKP和RTC。低功耗则其实是STM32四种模式中的三种耗能很低的模式。
目录
一#xff1a;备用区域
1.BKP
2.RTC
二#xff1a;低功耗模式
1.睡眠模式#xff1a;
2.停机模式#xff1a;
3.待机模式#xff1a; 一…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.hRTC_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所以溢出值设定为32767HAL_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所以溢出值设定为32767HAL_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.hvoid 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);
}
注意虽然这里的中断只是为了唤醒系统而不做任何操作但也必须完整写下来。
祝你看完就会。