stm32的低功耗模式
程序员文章站
2022-07-02 09:48:31
...
本文以smt32L4R5ZIT6单片机为例,编写代码。本文只讲代码,不说废话。
单片机进入低功耗前,都应该关闭中断。同时在低功耗前加上如下代码功耗更低
__HAL_RCC_PWR_CLK_ENABLE();//使能电源时钟
HAL_PWR_EnableBkUpAccess();//使能LSE/RTC控制的备份域
LSE_OFF_Config();//关闭LSE时钟,确保RTC关闭
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);//配置内部调节器输出电压(默认为Range1)
__HAL_RCC_PWR_CLK_DISABLE();//关闭电源时钟
在进入低功耗前,都要求设置GPIO为模拟输入模式,代码如下
void GPIO_AnalogState_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = GPIO_PIN_All;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_GPIOE_CLK_DISABLE();
__HAL_RCC_GPIOF_CLK_DISABLE();
__HAL_RCC_GPIOG_CLK_DISABLE();
__HAL_RCC_GPIOH_CLK_DISABLE();
}
void RTC_Config()函数
void RTC_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
__HAL_RCC_RTC_ENABLE();
}
1关断模式SHUTDOWN
关断模式
void test_shutdown(void)
{
GPIO_AnalogState_Config();//设置GPIO为模拟输入
__HAL_RCC_PWR_CLK_ENABLE();//使能电源时钟
HAL_PWREx_EnterSHUTDOWNMode();//进入shutdown模式
}
2待机模式standby
待机模式
void test_standby_rtc(void)
{
/* set RTC clock */
//说明:这里可以设置RTC时钟唤醒待机模式,但是本文未设置RTC中断,所以此处代码省略.如果想要唤醒,应该在此处开启rtc唤醒
RTC_Config();//配置RTC,因为前文介绍低功耗前关闭RTC,此处相当于重新打开
GPIO_AnalogState_Config();//设置GPIO为低功耗模式
__HAL_RCC_PWR_CLK_ENABLE();//使能电源时钟
HAL_PWR_EnterSTANDBYMode();//进入STANDBY模式
}
3待机模式+RTC
待机模式+RTC并保留sram2中数据
void test_standby_rtc_sram2(void)
{
/* set RTC clock */
/*这里可以设置RTC唤醒待机模式,但本文未设置,所以此处代码省略*/
MX_RTC_Init();//初始化RTC
GPIO_AnalogState_Config();//设置GPIO低功耗模式
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);//清除电源标志
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);//清除RTC唤醒定时器标志
__HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();//清除睡眠外部中断唤醒标志
__HAL_RTC_TIMESTAMP_CLEAR_FLAG(&hrtc, RTC_FLAG_TSF);
__HAL_RTC_TAMPER_TIMESTAMP_EXTI_CLEAR_FLAG();
__HAL_RCC_PWR_CLK_ENABLE();//使能电源时钟
/* Request to enter STANDBY mode with SRAM2 active */
HAL_PWREx_EnableSRAM2ContentRetention();//**待机模式中SRAM2备份域
// HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);//此代码是设置RTC定时器唤醒中断,5秒唤醒.此处作为示例代码,暂不使用
HAL_PWR_EnterSTANDBYMode();//进入待机模式
}
4停止模式stop2
停止模式2
void test_stop2(void)
{
GPIO_AnalogState_Config();
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);//进入停止模式2
}
5停止模式2+RTC
void test_stop2_rtc(void)
{
GPIO_AnalogState_Config();
MX_RTC_Init();//配置RTC
/* Enable Power Clock */
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
/* Clear RTC Wake Up timer Flag */
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
__HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();
__HAL_RTC_TIMESTAMP_CLEAR_FLAG(&hrtc, RTC_FLAG_TSF);
__HAL_RTC_TAMPER_TIMESTAMP_EXTI_CLEAR_FLAG();
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);//设置RTC定时器唤醒,定时5s
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);//进入停止2模式
SystemClock_80MHz(); //RTC定时5秒后唤醒,必须重新配置时钟
}
6停止模式1
停止模式1
void test_stop1_mroff(void)
{
GPIO_AnalogState_Config();
__HAL_RCC_PWR_CLK_ENABLE();
/*进入停止模式1,主调节器关,低功耗调节器开*/
HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
}
7停止模式1+RTC
停止模式1+RTC
void test_stop1_mroff_rtc(void)
{
/* set RTC clock */
/*这里可以设置RTC时钟唤醒*/
RTC_Config();//配置RTC
GPIO_AnalogState_Config();
__HAL_RCC_PWR_CLK_ENABLE();
/* Enter STOP 1 mode (Main Regulator OFF and Low Power Regulator On) */
HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
}
8低功耗睡眠模式2MHz
lpsleep_2mhz
void SystemClock_2MHz(void)//配置运行时钟为2MHz
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
/* MSI is enabled after System reset, update MSI to 2Mhz (RCC_MSIRANGE_5) */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
void test_lpsleep_2mhz(void)//睡眠模式配置
{
GPIO_AnalogState_Config();
__HAL_FLASH_SLEEP_POWERDOWN_ENABLE(); //在睡眠模式下启用flash power down,如果在低功耗下不需要flash进入待机模式,需要屏蔽这行代码
SystemClock_2MHz();//配置2MHz(MSI)单片机运行时钟频率
HAL_SuspendTick();//暂停时间增量防止系统中断唤醒,否则Systick中断在1ms内会唤醒设备
/* 关闭所有时钟使能*/
RCC->AHB1SMENR = 0x0;
RCC->AHB2SMENR = 0x0;
RCC->AHB3SMENR = 0x0;
RCC->APB1SMENR1 = 0x0;
RCC->APB1SMENR2 = 0x0;
RCC->APB2SMENR = 0x0;
__HAL_RCC_PWR_CLK_ENABLE();
/*进入睡眠模式,主调节器关闭*/
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
9运行模式2MHz
2MHz的运行模式
void SystemClock_2MHz(void)//配置运行时钟为2MHz
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
/* MSI is enabled after System reset, update MSI to 2Mhz (RCC_MSIRANGE_5) */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
void test_lprun_2mhz(void)//配置2MHz的低功耗运行模式
{
GPIO_AnalogState_Config();
SystemClock_2MHz();//配置系统时钟2 MHz (MSI)
HAL_SuspendTick();//暂停时间增量以防止系统中断唤醒。
__HAL_RCC_LPUART1_CLK_DISABLE();//失能低功耗串口时钟
__HAL_RCC_PWR_CLK_ENABLE();//开启电源时钟
HAL_PWREx_EnableLowPowerRunMode();//低功耗运行模式2MHz
__HAL_RCC_PWR_CLK_DISABLE();//失能电源时钟
}
10睡眠模式range2(24MHz)
void SystemClock_24MHz(void)//配置24MHz时钟
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
/* MSI is enabled after System reset, update MSI to 24Mhz (RCC_MSIRANGE_9) */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_9;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
}
void test_sleep_range2_24mhz(void)//设置睡眠模式
{
GPIO_AnalogState_Config();
SystemClock_24MHz();//配置系统时钟24 MHz (MSI)
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2);//配置内部主调节器输出电压
HAL_SuspendTick();//暂停Systick中断
RCC->AHB1SMENR = 0x0; //关闭所有时钟使能
RCC->AHB2SMENR = 0x0;
RCC->AHB3SMENR = 0x0;
RCC->APB1SMENR1 = 0x0;
RCC->APB1SMENR2 = 0x0;
RCC->APB2SMENR = 0x0;
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);//进入睡眠模式,主调节器开
}
11睡眠模式range1(80MHz)
sleep_range1_80mhz
void SystemClock_80MHz(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
/* MSI is enabled after System reset, activate PLL with MSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLP = 7;
RCC_OscInitStruct.PLL.PLLQ = 4;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
}
void test_sleep_range1_80mhz(void)
{
GPIO_AnalogState_Config();
SystemClock_80MHz();//配置系统频率80 MHz (MSI)
HAL_SuspendTick();
RCC->AHB1SMENR = 0x0;
RCC->AHB2SMENR = 0x0;
RCC->AHB3SMENR = 0x0;
RCC->APB1SMENR1 = 0x0;
RCC->APB1SMENR2 = 0x0;
RCC->APB2SMENR = 0x0;
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);//睡眠模式主调节器开
}
12运行模式range2(24MHz)
void SystemClock_24MHz(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
/* MSI is enabled after System reset, update MSI to 24Mhz (RCC_MSIRANGE_9) */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_9;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
}
void test_run_range2_24mhz(void)
{
SystemClock_24MHz();//设置系统时钟为24 MHz
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2);//设置内部主调节器输出电压
__HAL_RCC_PWR_CLK_DISABLE();
GPIO_AnalogState_Config();
__HAL_RCC_LPUART1_CLK_DISABLE();//关闭低功耗串口
HAL_SuspendTick();
}
13运行模式range1(80MHz)
void SystemClock_80MHz(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
/* MSI is enabled after System reset, activate PLL with MSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLP = 7;
RCC_OscInitStruct.PLL.PLLQ = 4;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
}
void test_run_range1_80mhz(void)
{
GPIO_AnalogState_Config();
__HAL_RCC_LPUART1_CLK_DISABLE();
SystemClock_80MHz();//配置系统时钟80 MHz (MSI)
HAL_SuspendTick();
}
至此,低功耗模式的代码呈现完毕。
下一篇: 采集数据