关闭

STM32待机模式唤醒测试以及独立看门狗测试

标签: 测试delay
11330人阅读 评论(1) 收藏 举报
分类:

STM32待机模式唤醒测试以及独立看门狗测试

 

本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.

 

环境:

主机:WIN7

开发环境:MDK4.23

MCU:STM32F103CBT6


说明:

在上篇文章中http://blog.csdn.net/jdh99/article/details/7369844,进行了一些STM32待机模式的测试.其中关于如何在再次启动时判断是否是待机模式没有进行测试.另外上篇文章有个问题,闹钟中断在待机模式下是进入不了的.

本文进行了独立看门狗IWDG测试,以及待机模式更详细的测试.

 

STM32中,复位分为3种:

1.系统复位:外部复位,WWDG,IWDG,SW复位,低功耗管理复位.除复位标志寄存器RCC_CSR不被复位,全部都被复位

2.电源复位:上电/掉电复位,从待机模式复位.上电/掉电复位除备份域外寄存器全部复位.待机复位不会复位备份域寄存器以及PWR_CSR寄存器.

3.备份域复位.

寄存器说明:

 

由图可以看出,可以通过WUF位来判断是否由待机模式唤醒.

 

RCC_CSR寄存器:

由图可以看出,RCC_CSR寄存器的IWDGRSTF位可以指示是否发生独立看门狗复位.

因为在看门狗复位时如果系统不处在待机模式,PWR_CSR寄存器也会被复位,所以WUF位也可以指示是否发生独立看门狗复位.

 

源代码:

独立看门狗复位测试:

//检查唤醒标志是否设置
if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET)
{
	//首次启动,或者独立看门狗复位 
	//初始化备份寄存器
	//BKP_DeInit();

	//RTC功能开启
	//使能外部晶振
	RCC_LSEConfig(RCC_LSE_ON);
	//等待外部晶振准备好
	while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

	//设置RTC时钟为外部晶振
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

	//使能RTC时钟
	RCC_RTCCLKCmd(ENABLE);
	//等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1
	RTC_WaitForSynchro();
	RTC_WaitForLastTask();  

	//使能闹钟中断   
	RTC_ITConfig(RTC_IT_ALR, ENABLE);  
	RTC_WaitForLastTask();  

	//分频系数为1,即最小时间单位1/2^15 = 30.5us
	RTC_SetPrescaler(RTC_PRESCALE);  
	RTC_WaitForLastTask();

	//启动独立看门狗
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); 					//访问之前要首先使能寄存器写
	IWDG_SetPrescaler(IWDG_Prescaler_64);							//64分频 一个周期1.6ms
	IWDG_SetReload(1250);											//最长12位 [0,4096] 1250*1.6 = 2s
	IWDG_ReloadCounter();											//喂狗
	//使能开门狗
	IWDG_Enable();	
	
	if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd)
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_11) ;
		BKP_WriteBackupRegister(BKP_DR6,0);
	}
	else
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_11) ;
		BKP_WriteBackupRegister(BKP_DR6,0xabcd);
	}											
}
else
{	
	//从待机模式中退出	
	//清除唤醒标志
	RCC_ClearFlag(); 

	if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd)
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_8) ;
		BKP_WriteBackupRegister(BKP_DR7,0);
	}
	else
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_8) ;
		BKP_WriteBackupRegister(BKP_DR7,0xabcd);
	}
}
while (1);


测试结果PA11引脚所连的LED不断闪烁,PA8所连的LED常亮,这说明不断进入看门狗复位.

 

待机模式RTC闹钟唤醒测试:

//检查唤醒标志是否设置
if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET)
{
	//首次启动,或者独立看门狗复位 
	//初始化备份寄存器
	//BKP_DeInit();

	//RTC功能开启
	//使能外部晶振
	RCC_LSEConfig(RCC_LSE_ON);
	//等待外部晶振准备好
	while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

	//设置RTC时钟为外部晶振
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

	//使能RTC时钟
	RCC_RTCCLKCmd(ENABLE);
	//等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1
	RTC_WaitForSynchro();
	RTC_WaitForLastTask();  

	//使能闹钟中断   
	RTC_ITConfig(RTC_IT_ALR, ENABLE);  
	RTC_WaitForLastTask();  

	//分频系数为1,即最小时间单位1/2^15 = 30.5us
	RTC_SetPrescaler(RTC_PRESCALE);  
	RTC_WaitForLastTask();

	//启动独立看门狗
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); 					//访问之前要首先使能寄存器写
	IWDG_SetPrescaler(IWDG_Prescaler_64);							//64分频 一个周期1.6ms
	IWDG_SetReload(1250);											//最长12位 [0,4096] 1250*1.6 = 2s
	IWDG_ReloadCounter();											//喂狗
	//使能开门狗
	//IWDG_Enable();	
	
	if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd)
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_11) ;
		BKP_WriteBackupRegister(BKP_DR6,0);
	}
	else
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_11) ;
		BKP_WriteBackupRegister(BKP_DR6,0xabcd);
	}											
}
else
{	
	//从待机模式中退出	
	//清除唤醒标志
	RCC_ClearFlag(); 

	if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd)
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_8) ;
		BKP_WriteBackupRegister(BKP_DR7,0);
	}
	else
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_8) ;
		BKP_WriteBackupRegister(BKP_DR7,0xabcd);
	}
}
//延时1s
for (i = 0;i < 100;i++)
{
   	_delay_ms(10);
}
//打开待机模式,1s后唤醒
open_standy_mode(30000);

每次刚上电所有LED会亮,进入待机模式则全部灭.测试结果PA8引脚所连的LED会亮1s进入灭进入待机模式,下次则常灭进入待机模式.PA11所连的LED随着低功耗进入正常亮灭,这说明不断发生闹钟唤醒(看门狗已关).

 

待机模式IWDG唤醒测试:

//检查唤醒标志是否设置
if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET)
{
	//首次启动,或者独立看门狗复位 
	//初始化备份寄存器
	//BKP_DeInit();

	//RTC功能开启
	//使能外部晶振
	RCC_LSEConfig(RCC_LSE_ON);
	//等待外部晶振准备好
	while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

	//设置RTC时钟为外部晶振
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

	//使能RTC时钟
	RCC_RTCCLKCmd(ENABLE);
	//等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1
	RTC_WaitForSynchro();
	RTC_WaitForLastTask();  

	//使能闹钟中断   
	RTC_ITConfig(RTC_IT_ALR, ENABLE);  
	RTC_WaitForLastTask();  

	//分频系数为1,即最小时间单位1/2^15 = 30.5us
	RTC_SetPrescaler(RTC_PRESCALE);  
	RTC_WaitForLastTask();

	//启动独立看门狗
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); 					//访问之前要首先使能寄存器写
	IWDG_SetPrescaler(IWDG_Prescaler_64);							//64分频 一个周期1.6ms
	IWDG_SetReload(1250);											//最长12位 [0,4096] 1250*1.6 = 2s
	IWDG_ReloadCounter();											//喂狗
	//使能开门狗
	IWDG_Enable();	
	
	if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd)
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_11) ;
		BKP_WriteBackupRegister(BKP_DR6,0);
	}
	else
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_11) ;
		BKP_WriteBackupRegister(BKP_DR6,0xabcd);
	}											
}
else
{	
	//从待机模式中退出	
	//清除唤醒标志
	RCC_ClearFlag(); 

	if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd)
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_8) ;
		BKP_WriteBackupRegister(BKP_DR7,0);
	}
	else
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_8) ;
		BKP_WriteBackupRegister(BKP_DR7,0xabcd);
	}
}

//延时1s
for (i = 0;i < 100;i++)
{
	_delay_ms(10);
}
	
//打开待机模式,2s后唤醒
open_standy_mode(60000);

 

每次刚上电所有LED会亮,进入待机模式则全部灭.测试结果PA11引脚所连的LED会亮1s进入灭进入待机模式,下次则常灭进入待机模式.PA8所连的LED随着低功耗进入正常亮灭,而且待机模式是待机2s加延时1s应该是3s唤醒,LED闪烁频率2s左右说明被提前唤醒.这说明不断发生看门狗唤醒.

 

完整的测试程序:判断出首次启动程序,单片机处于正常状态时看门狗复位,单片机处于待机模式下被闹钟唤醒/看门狗唤醒.

注意:每次看门狗复位都要被重新配置启动

//检查是否正常状态发生看门狗复位
if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
{
	//清楚标志位
	RCC_ClearFlag();

	//RTC功能开启
	//使能外部晶振
	RCC_LSEConfig(RCC_LSE_ON);
	//等待外部晶振准备好
	while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);

	//设置RTC时钟为外部晶振
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

	//使能RTC时钟
	RCC_RTCCLKCmd(ENABLE);
	//等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1
	RTC_WaitForSynchro();
	RTC_WaitForLastTask();  

	//使能闹钟中断   
	RTC_ITConfig(RTC_IT_ALR, ENABLE);  
	RTC_WaitForLastTask();  

	//分频系数为1,即最小时间单位1/2^15 = 30.5us
	RTC_SetPrescaler(RTC_PRESCALE);  
	RTC_WaitForLastTask();

	//启动独立看门狗
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); 					//访问之前要首先使能寄存器写
	IWDG_SetPrescaler(IWDG_Prescaler_64);							//64分频 一个周期1.6ms
	IWDG_SetReload(1250);											//最长12位 [0,4096] 1250*1.6 = 2s
	IWDG_ReloadCounter();											//喂狗
	//使能开门狗
	IWDG_Enable();

	if (BKP_ReadBackupRegister(BKP_DR5) == 0xabcd)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_12) ;
		BKP_WriteBackupRegister(BKP_DR5,0);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_12) ;
		BKP_WriteBackupRegister(BKP_DR5,0xabcd);
	}	
}
else
{
	//检查唤醒标志是否设置,判断是否首次启动
	if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET)
	{
		//首次启动
		//初始化备份寄存器
		//BKP_DeInit();

		//RTC功能开启
		//使能外部晶振
		RCC_LSEConfig(RCC_LSE_ON);
		//等待外部晶振准备好
		while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
	
		//设置RTC时钟为外部晶振
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
	
		//使能RTC时钟
		RCC_RTCCLKCmd(ENABLE);
		//等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1
		RTC_WaitForSynchro();
		RTC_WaitForLastTask();  

		//使能闹钟中断   
		RTC_ITConfig(RTC_IT_ALR, ENABLE);  
		RTC_WaitForLastTask();  

		//分频系数为1,即最小时间单位1/2^15 = 30.5us
		RTC_SetPrescaler(RTC_PRESCALE);  
		RTC_WaitForLastTask();

		//启动独立看门狗
		IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); 					//访问之前要首先使能寄存器写
		IWDG_SetPrescaler(IWDG_Prescaler_64);							//64分频 一个周期1.6ms
		IWDG_SetReload(1250);											//最长12位 [0,4096] 1250*1.6 = 2s
		IWDG_ReloadCounter();											//喂狗
		//使能开门狗
		IWDG_Enable();	
		
		if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd)
		{
			GPIO_ResetBits(GPIOA, GPIO_Pin_11) ;
			BKP_WriteBackupRegister(BKP_DR6,0);
		}
		else
		{
			GPIO_SetBits(GPIOA,GPIO_Pin_11) ;
			BKP_WriteBackupRegister(BKP_DR6,0xabcd);
		}											
	}
	else
	{	
		//从待机模式中退出,有闹钟唤醒或者看门狗唤醒	
		//清除唤醒标志
		RCC_ClearFlag(); 

		if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd)
		{
			GPIO_ResetBits(GPIOA, GPIO_Pin_8) ;
			BKP_WriteBackupRegister(BKP_DR7,0);
		}
		else
		{
			GPIO_SetBits(GPIOA,GPIO_Pin_8) ;
			BKP_WriteBackupRegister(BKP_DR7,0xabcd);
		}
	}
}

//延时1s
for (i = 0;i < 100;i++)
{
	_delay_ms(10);
}

//打开待机模式,2s后唤醒
open_standy_mode(60000);
7
0
查看评论

低功耗STM32L151+RTC唤醒应用总结

该文档是本人做一个睡眠+RTC唤醒的低功耗项目总结心得,如有出入请指出。   STM32L提供5种低功耗模式:低功耗运行模式、睡眠模式、低功耗睡眠模式、停止模式、待机模式。     待机模式电流最低,但是待机模式时MCU处于不受控制的状态,所有的IO...
  • zhufeng88
  • zhufeng88
  • 2017-03-27 09:35
  • 4518

定时器、看门狗和RTC

注:本文学习朱有鹏老师课程和自己整理而成。方便今后查阅,感谢朱老师~ 什么是定时器(timer) 1.定时器是SoC中常见外设 1、定时器与计数器。计数器是用来计数的(每隔一个固定时间会计一个数);因为计数器的计数时间周期是固定的,因此到了一定时间只要用计数值×计数时间周期,就能...
  • czg13548930186
  • czg13548930186
  • 2016-10-10 23:58
  • 3970

STM32 休眠模式下如何喂狗?

在STM32开发中经常会用到独立看门狗(IWDG)和低功耗模式,看门狗是为了检测和解决由软件错误引起的故障,低功耗模式是为了在CPU不需要继续运行时进入到休眠模式用以节省电能。其中独立看门狗的时钟由独立的RC振荡器(STM32F10x一般为40kHz)提供,即使在主时钟出现故障时,也仍然有效,因此可...
  • feihu521a
  • feihu521a
  • 2013-01-08 09:16
  • 11984

stm32f103 RTC周期性待机唤醒(一)

做一个低功耗的东西,搞了好几天,程序一直卡在一个地方(见下图),今天终于发现问题出在哪里了,对待机唤醒的问题做一个总结(只针对我遇到的问题,其他部分网上都有,基于stm32f103) 1、解决我遇到的问题        我的RTC初始化部分有个“保存在备份...
  • u011732167
  • u011732167
  • 2016-03-22 22:16
  • 8068

亲测实验,stm32待机模式和停机模式唤醒程序的区别,以及唤醒后程序入口。

本文主要研究STM32的低功耗知识,包括待机模式和停机模式。让单片机进入的待机模式和停机模式,并且分别对它唤醒。观察现象,得出唤醒机理。
  • ludaoyi88
  • ludaoyi88
  • 2016-03-09 15:49
  • 15459

stm32的待机模式解析

stm32的待机模式解析
  • u013256018
  • u013256018
  • 2014-12-05 18:15
  • 1997

STM32之待机唤醒

待机唤醒 在本章中,我们将学习STM32的待机唤醒功能,通过 WK_UP(高电平触发)按键来实现唤醒和进入待机模式的功能,然后使用 DS0 指示状态。 很多单片机都有低功耗模式,STM32 也不例外。在系统或电源复位以后,微控制器处于运行状态。运行状态...
  • u010188552
  • u010188552
  • 2013-08-04 15:52
  • 1436

stm32休眠 以及休眠中如何喂狗

在STM32开发中经常会用到独立看门狗(IWDG)和低功耗模式,看门狗是为了检测和解决由软件错误引起的故障,低功耗模式是为了在CPU不需要继续运行时进入到休眠模式用以节省电能。其中独立看门狗的时钟由独立的RC振荡器(STM32F10x一般为40kHz)提供,即使在主时钟出现故障时,也仍然有效,因此可...
  • leee7338
  • leee7338
  • 2015-10-07 09:36
  • 2445

STM32之独立看门狗的那些事

为什么MCU会具有看门狗呢?带着这个疑问,来了解看门狗的那些事。就连51单片机都带有看门狗,说明这条狗对我们来说有着 不一般的意义。看门狗的目的一句话说:防止程序乱跑。MCU在不同的环境下程序的运行会受到干扰,比如陷入死循环怎么办? 这就是养狗的好处呀,就算你没养过狗,你也看过猪跑吧。 ...
  • m0_38005870
  • m0_38005870
  • 2017-06-19 12:48
  • 303

STM32F0xx_看门狗(独立+窗口)配置详细过程

Ⅰ、概述 对于看门狗,我觉得做单片机或者嵌入式开发的人员来说并不陌生,今天总结STM32F0看门狗的功能,F0的看门狗有两种:独立和窗口看门狗。 今天提供两种看门狗的软件工程实例,供大家下载。 两种看门狗各有各的特点,应用在不同的场合,下面将分别简单总结一下独立和窗口看门狗的功能。 ...
  • ybhuangfugui
  • ybhuangfugui
  • 2016-06-07 22:10
  • 3111
    个人资料
    • 访问:1353146次
    • 积分:14838
    • 等级:
    • 排名:第944名
    • 原创:182篇
    • 转载:19篇
    • 译文:0篇
    • 评论:597条
    博客专栏
    文章分类
    最新评论
    友情链接