知识回顾
https://blog.csdn.net/weixin_63809529/article/details/138293874
其中,重要的内容
简单介绍一下
stm32有三种低功耗
其实他们是递进的关系,
基础操作位__wfi(),这一个汇编命令,就可以进入睡眠模式。
停机是在睡眠的模式上,关闭一些功能(这个功能如1.8V供电区域的的所有时钟都被停止,PLL、HSI和HSE RC振荡器的功能被禁止,也可以是自己添加的功能)
待机就是“软启动”。
怎么进入睡眠模式
为了实验现象,先配置LED灯和窜口。我使用的是stm32c8t6芯片。led灯是自带PC13,和串口1。
串口配置可以参考:
https://blog.csdn.net/Qxiaofei_/article/details/119029425
进入低功耗
核心代码
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
LED_ON;
HAL_Delay(500);
printf("进入睡眠模式\r\n");
HAL_Delay(500);
HAL_SuspendTick(); //停止系统滴答计时器
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
HAL_ResumeTick(); //释放滴答定时器
HAL_Delay(500);
printf("退出睡眠模式\r\n");
LED_OFF;
HAL_Delay(500);
}
效果
默认情况下,进入串口显示“进入睡眠模式”后,就可以休眠,当串口接收函数接受中断后,就会退出睡眠。
因为while(1),所有再次睡眠。
细节一
注意,当进入睡眠时,keil无法直接下载代码。
这是需要安装重启键下载,就可以了。
细节二
有些人好像无法进入睡眠模式,可能是滴答定时器一直在产生中断,有可能是其他的中断
可以参考:
https://blog.csdn.net/weixin_53403301/article/details/129119434
我使用的是,停止滴答定时器。
进入停止模式
停止模式和睡眠模式,最大的区别为:
此时在1.8V供电区域的的所有时钟都被停止,PLL、HSI和
HSE RC振荡器的功能被禁止,SRAM和寄存器内容被保留下来。
细节一
在退出停止模式后,要重新配置时钟。
细节二
停止模式无法用串口唤醒,所以我用外部中断PB9来唤醒。
https://blog.csdn.net/txmnQAQ/article/details/121128233
我就用 SystemClock_Config()来重新配置时钟,保证串口还可以用。
printf("进入停止模式\r\n");
HAL_Delay(500);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_SLEEPENTRY_WFI);//进入停止模式
SystemClock_Config(); //重新配置时钟
HAL_Delay(500);
printf("退出停止模式\r\n");
这个使用外部中断触发的,PB9,不是串口来触发!!!
进入待机模式
关于待机模式的特点,我之前讲过,所以不讲了。
直接上代码
printf("进入待机模式\r\n");
HAL_Delay(500);
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); //配置唤醒引脚 PA0
HAL_PWR_EnterSTANDBYMode();//进入待机模式
//退出待机模式程序会重新开始执行,所有后面没代码
细节一
待机模式,相当于软启动。就是如果退出待机模式,代码会重头执行,不会接着执行。相当于重启了一次。
源码例程(可以直接来看这里)
这里先放main.c,全部的代码可以来我的仓库https://github.com/wan71/stm32-hal/tree/main/hal_test1
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
enum LowPower mode;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//mode=SLEEP; //选择睡眠模式
mode=STOP; //选择停止模式
// mode=STANDBY; //选择待机模式
LED_ON;
HAL_Delay(500);
switch(mode)
{
case SLEEP:
printf("进入睡眠模式\r\n");
HAL_Delay(500);
HAL_SuspendTick(); //停止系统滴答计时器
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON,PWR_SLEEPENTRY_WFI); //进入睡眠模式
HAL_ResumeTick(); //释放滴答定时器
HAL_Delay(500); //等待滴答定时器释放
printf("退出睡眠模式\r\n");
break;
case STOP:
printf("进入停止模式\r\n");
HAL_Delay(500);
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_SLEEPENTRY_WFI);//进入停止模式
SystemClock_Config(); //重新配置时钟
HAL_Delay(500);
printf("退出停止模式\r\n");
break;
case STANDBY:
printf("进入待机模式\r\n");
HAL_Delay(500);
HAL_SuspendTick(); //停止系统滴答计时器
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); //配置唤醒引脚 PA0
HAL_PWR_EnterSTANDBYMode();//进入待机模式
//退出待机模式程序会重新开始执行,所有后面没代码
break;
default:
break;
}
LED_OFF;
HAL_Delay(500);
}
/* USER CODE END 3 */
}