
基于 STM32F103 HAL 库代码可直接编译运行并且教你如何测量电流验证是否真的睡下去了。一、STM32 低功耗模式速查模式唤醒方式唤醒后典型功耗适用场景Sleep任意中断立即执行mA 级只是让 CPU 歇一下StopEXTI按键需要重配时钟μA 级电池供电首选StandbyWakeUp 引脚 / RTC相当于复位 5μA极低功耗但麻烦90% 的项目用 Stop 模式就够了二、Stop 模式测试程序1、GPIO 设计引脚功能PA0唤醒按键EXTI0PC13LED闪烁表示运行其余 IO设为Analog省电2、主程序main.c#includemain.hvoidSystemClock_Config(void);voidEnter_STOP_Mode(void);intmain(void){HAL_Init();SystemClock_Config();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitStruct{0};// PC13 LEDGPIO_InitStruct.PinGPIO_PIN_13;GPIO_InitStruct.ModeGPIO_MODE_OUTPUT_PP;GPIO_InitStruct.SpeedGPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC,GPIO_InitStruct);// PA0 唤醒按键GPIO_InitStruct.PinGPIO_PIN_0;GPIO_InitStruct.ModeGPIO_MODE_IT_RISING;GPIO_InitStruct.PullGPIO_NOPULL;HAL_GPIO_Init(GPIOA,GPIO_InitStruct);HAL_NVIC_EnableIRQ(EXTI0_IRQn);while(1){// 运行指示HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);HAL_Delay(200);// 运行 2 秒后进入 STOPstaticuint32_tcnt0;if(cnt10){cnt0;HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);Enter_STOP_Mode();}}}3、进入 Stop 模式voidEnter_STOP_Mode(void){__HAL_RCC_PWR_CLK_ENABLE();// 关闭所有不需要的外设时钟__HAL_RCC_USART1_CLK_DISABLE();__HAL_RCC_SPI1_CLK_DISABLE();__HAL_RCC_TIM2_CLK_DISABLE();// 配置所有 IO 为模拟输入最省电GPIO_InitTypeDef GPIO_InitStruct{0};GPIO_InitStruct.ModeGPIO_MODE_ANALOG;GPIO_InitStruct.PullGPIO_NOPULL;GPIO_InitStruct.SpeedGPIO_SPEED_FREQ_LOW;GPIO_InitStruct.PinGPIO_PIN_All;HAL_GPIO_Init(GPIOA,GPIO_InitStruct);HAL_GPIO_Init(GPIOB,GPIO_InitStruct);HAL_GPIO_Init(GPIOC,GPIO_InitStruct);// 进入 STOP 模式唤醒后使用 HSIHAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);}4、唤醒后恢复时钟voidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){if(GPIO_PinGPIO_PIN_0){// 重新初始化系统时钟STOP 唤醒后默认用 HSISystemClock_Config();// 重新初始化 GPIO__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();GPIO_InitTypeDef GPIO_InitStruct{0};GPIO_InitStruct.PinGPIO_PIN_13;GPIO_InitStruct.ModeGPIO_MODE_OUTPUT_PP;GPIO_InitStruct.SpeedGPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC,GPIO_InitStruct);}}三、SystemClock_Config标准 72MHzvoidSystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct{0};RCC_ClkInitTypeDef RCC_ClkInitStruct{0};RCC_OscInitStruct.OscillatorTypeRCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEStateRCC_HSE_ON;RCC_OscInitStruct.PLL.PLLStateRCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSourceRCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMULRCC_PLL_MUL9;HAL_RCC_OscConfig(RCC_OscInitStruct);RCC_ClkInitStruct.ClockTypeRCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSourceRCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDividerRCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDividerRCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDividerRCC_HCLK_DIV1;HAL_RCC_ClockConfig(RCC_ClkInitStruct,FLASH_LATENCY_2);}四、如何验证是否真的睡下去了方法 1万用表测电流最准状态电流运行10~30 mASleep5~10 mAStop≈ 20~50 μAStandby 5 μA如果 Stop 模式 1mA一定有问题2、方法 2LED 行为运行LED 快速闪烁睡眠LED 熄灭唤醒LED 再次闪烁参考代码 睡眠模式测试程序www.youwenfan.com/contentcsv/103598.html五、常见问题问题原因睡不下去外设没关时钟唤醒后死机没重配系统时钟电流很大IO 没设为 Analog自动唤醒没关滴答定时器串口失效STOP 后 USART 时钟没了六、彻底省电关闭 SysTick 再睡HAL_SuspendTick();// 禁止 SysTickHAL_PWR_EnterSTOPMode(...);HAL_ResumeTick();// 恢复 SysTick七、Standby 模式HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);HAL_PWR_EnterSTANDBYMode();唤醒 复位重启