STM32在休眠模式(Stop/Standby)模式下的关闭看门狗问题的解决

本文介绍了一种在STM32微控制器启用IWDG看门狗后,通过设置标识并控制重启流程,实现休眠过程的可靠方法——两步法。通过读写闪存存储标识,确保在唤醒后执行正确的操作,提高产品的稳定性和寿命。

长期以来一直都认为Stm32启用了IWDG看门狗以后,就不能再使用休眠进入低功耗模式。由于看门狗启动后就不能停止,给很多人带来了困扰。还有很多人放弃了使用看门狗,从而给产品带来一定的不确定性。

其实有一个简单的方法可以实现在有看门狗的情况下可靠休眠。我起名字为“两步法”。顾名思义:

第一步:在flash或任何可以保存的位置上,写入一个标识,比如1;然后执行单片机重启,比如NVIC_SystemReset()

第二步:重启后的main入口中,在启用看门狗之前,先检测上述标识,如果是1,先清掉这个1,改为0,保存,然后进入真正的休眠过程比如Sys_Standby(){。。。};如果不是1,那么显然,这个是唤醒的过程了。直接进入后面的程序就好。

//standby 为flash中某个地址
//执行休眠前的标识设置和重启
void Pre_Standby(void){
	standby=1;
	WriteParam2Flash();
	NVIC_SystemReset();
}
//执行真正的休眠
void Sys_StandbyReal(void){
	RCC_APB2PeriphResetCmd(0x01fc, DISABLE);//关闭所有管脚
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);	//使能PWR外设时钟
	PWR_WakeUpPinCmd(ENABLE);  //使能唤醒管脚功能
	PWR_EnterSTANDBYMode();	  //进入待命(STANDBY)模式 		 
}

//入口
void  main(void){
//各种初始化

。。。
ReadParamFlash();//读取flash部分
    if(standby==1){//真正进入休眠 否则就是真开机
		standby=0;
		WriteParam2Flash();//再次保存
		Sys_StandbyReal();		
	}
IWDG_Config();//设置看门狗 要放在标识检测后面
//以下是主程序
...
    while(1){
        ...
        IWDG_FEED();
    }
}

//调用休眠时,执行Pre_Standby();

虽然要读写2次flash,但比起产品本身的寿命和程序的可靠性来还是划算多了,当然也可以保存在外部的eprom中,这样寿命就大大增加了。另外我想也可以保存在休眠后依然能保存的寄存器中,我还没去研究,知道的可以回复我。

### STM32低功耗模式下独立看门狗配置与使用 #### 1. 理解STM32的低功耗特性 STM32微控制器具备高性能、丰富的外设资源以及多种低功耗模式,如休眠模式和待机模式。这些模式允许设备在不需要全功率运行的情况下节省电力[^1]。 #### 2. 独立看门狗(IWDG)的工作原理 独立看门狗利用内部较低频率的LSI振荡器作为时钟源,在默认情况下即使进入低功耗状态也不会停止计数。这意味着如果应用程序未能及时刷新看门狗,则可能导致意外复位。对于某些应用来说,这可能是一个问题特别是当MCU处于长时间睡眠状态下[^2]。 #### 3. 解决方案概述 为了克服上述挑战并确保系统稳定性和节能效果之间的平衡,可以通过调整选项字节来改变看门狗的行为方式: - **OB_USER_IWDG_STOP**: 当此位被设置为1时, 进入STOP/STANDBY Mode 后 IWDG 的计数器会继续工作. - **OB_IWDG_STOP_FREEZE**: 设置该位后, 在 STOPSTANDBY mode 下,IWDG 计数器将会暂停直到退出相应模式. 通过适当配置这两个参数可以在不影响安全性的前提下减少不必要的唤醒次数从而达到更好的省电目的[^5]. #### 4. 实现步骤 (基于HAL库) ##### 初始化阶段: ```c // 修改Flash Options Bytes以启用看门狗冻结功能 void HAL_MspInit(void){ /* ...其他初始化代码... */ // 配置Option Byte使能看门狗停机期间冻结 HAL_FLASH_OB_Unlock(); OB InitiStruct.Instance = FLASH_OB; OB_InitStruc.UserConfig |= OB_USER_IWDG_STOP | OB_IWDG_STOP_FREEZE; HAL_FLASHEx_OBProgram(&OB_InitStruc); HAL_FLASH_OB_Lock(); // 开启独立看门狗 __HAL_RCC_IWDG_CLK_ENABLE(); } ``` ##### 正常操作流程中的处理逻辑: ```c if(/*条件满足*/){ // 准备进入低功耗之前先触发一次软件复位 NVIC_SystemReset(); }else{ // 继续执行常规任务... } ``` ##### 唤醒后的响应措施: ```c void SystemClock_Config(void){ // 检查是否是从硬件复位恢复过来 if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST)){ // 清除标志位 __HAL_RCC_CLEAR_RESET_FLAGS(); // 跳过喂狗过程直接进入低功耗管理部分 EnterLowPowerMode(); }else{ // 执行正常的启动序列... } } void EnterLowPowerMode(){ // 关闭所有非必要的外围设备电源供应 // 设置RTC闹钟用于定时唤醒 RTC_AlarmTypeDef sAlarm = {0}; sAlarm.AlarmTime.Hours = 0; sAlarm.AlarmTime.Minutes = 0; sAlarm.AlarmTime.Seconds = 60;//每分钟唤醒一次为例 HAL_RTC_SetAlarm_IT(&hrtc,&sAlarm,FORMAT_BIN); // 切换至最低能耗模式(Standby) HAL_PWR_EnterSTANDBYMode(); } ``` 以上代码片段展示了如何在一个实际项目中实现这一机制。需要注意的是具体细节可能会因所使用的特定型号而有所不同,请参照官方文档获取最准确的信息[^4]。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csaaa2005

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值