ST线下培训(05-23成都站)STM32L476低功耗设计(三)
——进入Stop2模式,延时5秒后唤醒
一、实验开始之前 上一章节次实验实现的是进入低功耗后测得的电流值,但在要在实际应用中,只能进入低功耗是不够的。需要能进入低功耗后根据实际需要和应用场景实现频率、电源的恢复,能恢复到进入低功耗前的处理能力。本章就针对进入Stop2模式 后的经过RTC定时五秒后恢复进行数据测量。
二、实验过程1、实验前探索1.1 RTC时钟源选择 在正式实验前,将功能树上的是RTC功能打开,并在时钟树上查看RTC时钟源频率。
从时钟数可以看到RTC时钟频率使用的是LSI RC的32KHz的频率。当然也能选择LSE或者HSE的RTC分频后的时钟作为RTC时钟源,进入除Shutdown模式外的低功耗(因实验中板卡为Nucleo L476RG 缺少LSE,无法对Shutdown模式进行唤醒,需要另外焊接LSE 的元器件后方可进行实验),将时钟源统一为LSI 的RC,具体的产品环境根据实际需要选择时钟源。 1.2 时钟源相关设置
设置唤醒时钟为 32K的16分频,频率为2K,唤醒定为5秒后,这里设置5*2K=10K次。
设置唤醒中断使能。 1.3 LSI时钟功耗 将LSI、RTC始终设置后,因增加了设备,会增加进入功耗时的功耗值,分别测试打开LSI、RTC后的功耗值如下: RUN: 15mA;(外设功能活动) SHUTDOWN: 0.09uA;(外设功能停止) STANDBY: 0.68uA;(外设功能停止) STOP2: 2.13uA;(外设功能停止) LPSLEEP2MHz: 87uA(外设功能活动);
2、实验步骤2.1 Stop2 模式使用RTC计数5秒后唤醒 2.1.1 唤醒方式LSI+ RTC 进入Stop2模式后,除LSI、LSE之外的所有时钟都将关闭; 触发唤醒的事件有:任意一线EXTI(已配置的EXTI寄存器)特定外设事件。 唤醒后的系统时钟有两种情况: 1、STOPWUCK=0时为进入Stop模式前的MSI频率; 2、RCC_CFGR寄存器中STOPWUCK=1时为HSI16; 进入Stop2模式前,设置好低功耗模式的时钟: - void Low_SystemClock_Config(void){
- RCC_OscInitTypeDef RCC_OscInitStruct;
- RCC_PeriphCLKInitTypeDef PeriphClkInit;
- RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_LSI;
- RCC_OscInitStruct.LSIState = RCC_LSI_ON;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- _Error_Handler(__FILE__, __LINE__);
- }
复制代码- PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
- PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
- if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
- {
- _Error_Handler(__FILE__, __LINE__);
- }
- /**Configure the main internal regulator output voltage
-
- */
- if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
- {
- _Error_Handler(__FILE__, __LINE__);
- }
- }
复制代码
RTC初始化,过去早的初始化RTC,增加正常工作时的功耗,若需要RTC在项目全生命周期工作的情况除外。 - tatic void MX_RTC_Init(void)
- {
- RTC_TimeTypeDef sTime;
- RTC_DateTypeDef sDate;
- /**Initialize RTC Only
- */
- hrtc.Instance = RTC;
- hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
- hrtc.Init.AsynchPrediv = 127;
- hrtc.Init.SynchPrediv = 255;
- hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
- hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
- hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
- hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
- if (HAL_RTC_Init(&hrtc) != HAL_OK)
- {
- _Error_Handler(__FILE__, __LINE__);
- }
复制代码- /**Initialize RTC and set the Time and Date
-
- */
- if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){
- sTime.Hours = 0x0;
- sTime.Minutes = 0x0;
- sTime.Seconds = 0x0;
- sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
- sTime.StoreOperation = RTC_STOREOPERATION_RESET;
- if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
- {
- _Error_Handler(__FILE__, __LINE__);
- }
- sDate.WeekDay = RTC_WEEKDAY_MONDAY;
- sDate.Month = RTC_MONTH_JANUARY;
- sDate.Date = 0x1;
- sDate.Year = 0x0;
- if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
- {
- _Error_Handler(__FILE__, __LINE__);
- }
- HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2);
- }
- }
复制代码
设置RTC从STOP模式唤醒后的系统时钟以及事件唤醒中断: - HAL_RCCEx_WakeUpStopCLKConfig(RCC_STOP_WAKEUPCLOCK_HSI);
- HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 20480, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
复制代码
随后就能进入STOP2模式了,直接调用Test_Stop2()。
在进入STOP2模式后, 经历RTC计数到达唤醒设定的延时时间,及触发RTC_WKUP中断, 在HAL生成的中断函数里调用了唤醒中断函数, HAL_RTCEx_WakeUpTimerIRQHandler(xxxx), 其中的HAL_RTCEx_WakeUpTimerEventCallback()回调函数,是需要根据开发者自己定义的,
- void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) {
- WakeUpState=1;
- }
复制代码考虑到唤醒中断优先级,这里只标记唤醒状态,具体唤醒后的操作交由主循环中的内容只执行: - ........
- if (WakeUpState){
- WakeUpState=0;
- //禁用RTC 定时器WakeUP,避免再次出发唤醒
- HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
- //初始化变量及引脚功能
- EXTI_State = DISABLE;
-
- //HAL_Init();
- SystemClock_Config();
- MX_GPIO_Init();
- MX_USART2_UART_Init();
- printf("\n\rWake Up From RTC \n\r");
- }
- ........
复制代码至此,RTC 唤醒的功能就完整了
STOP2 状态定时5秒唤醒动图:
代码参考前一章节的内容作了适当调整,见附件Main.rar
main.rar
(6.04 KB, 下载次数: 115)
|