STM32睡眠模式的唤醒 讨论

[复制链接]
20945|21
 楼主| wudingzhiying 发表于 2012-2-22 14:46 | 显示全部楼层 |阅读模式
手册上说睡眠是可以用任何一个中断唤醒的,那么我想着应该包括ADC和串口,至于timer能不能唤醒,我想是不能的,应为timer是在cpu内部的,进入睡眠之后就会关闭内核,timer肯定也会关闭的。
在工程中加入.c文件,stm32f10x_pwr.c,这里里面包含着关于PWR的各种操作函数,主程序中加入头文件stm32f10x_pwr.h。
main函数中首先开启PWR时钟:RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);   
然后初始化PWR。我调用的语句是:PWR_DeInit();
PWR_BackupAccessCmd(DISABLE);
然后期望进入睡眠状态,语句是:SCB->SCR |= SCB_SCR_SLEEPDEEP;
__WFI();
  SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
(这是在网上搜到的。设置sleepdeep位,然后执行_WFI指令)


现在应该已经进入睡眠状态了吧??我后面定义了ADC的装换结束中断,ADC是以软件方式开启转换,独立非连续转换,所以是转换一次,中断一次,再在主程序中软件出发一次,如此往复。但是进入睡眠之后就一动不动,没法唤醒,请高手帮忙解答一下,我们讨论讨论。谢谢
香水城 发表于 2012-2-22 15:28 | 显示全部楼层
请LZ看看ST的手册和固件库的例程,没有"设置sleepdeep位,然后执行_WFI指令"这个说法。
香水城 发表于 2012-2-22 15:30 | 显示全部楼层
这是ST手册中的列表,细节你可以自己看看。
STM32_Low_Power_Mode.GIF
 楼主| wudingzhiying 发表于 2012-2-22 17:43 | 显示全部楼层

没有"设置sleepdeep位,然后执行_WFI指令"这个说法

2# 香水城
、谢谢你的提醒。这个确实是我自己理解错误了。 1.png 这个地方应该是让SLEEPDEEP=0,而不是置位,谢谢。
 楼主| wudingzhiying 发表于 2012-2-22 17:50 | 显示全部楼层
3# 香水城
谢谢。
虽然这个表中说执行WFI或者WFE都能进入sleep模式,但是我看在固件库中无论是void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry);还是void PWR_EnterSTANDBYMode(void);里面都有设置SLEEPDEEP位的语句:
2.png
那是不是可以说睡眠模式和停止模式,待机模式是不一样的?因为一个是保证SLEEPDEEP位为0,而后面两种是置位这一位?请赐教
谢谢
香水城 发表于 2012-2-22 18:18 | 显示全部楼层
参考3楼的表格:

睡眠模式 对应 SLEEP
停止模式 对应 STOP
待机模式 对应 Standby

他们显然是不一样的。
240899105lcq 发表于 2013-6-4 17:35 | 显示全部楼层
你好,想问下楼主,你的睡眠可以退出吗?我的也退不出来
zeluo 发表于 2013-6-4 18:29 | 显示全部楼层
还是版主给力   不错   顶一个
mingjiezhong 发表于 2013-10-19 18:03 | 显示全部楼层
我也正好要搞这个,参考一下,按照BSP库里的写法,在执行WFI 前要开中断,还要允许唤醒
trumpxp 发表于 2013-10-19 19:58 | 显示全部楼层
还是不是很熟悉技术手册   将技术手册仔细钻研钻研   应该就出来了  楼主
wilson970 发表于 2014-5-8 20:05 | 显示全部楼层
我调了一个RTC ALARM 唤醒,发现简单测试可以运行很好,但当程序开始执行大量的任务就老是不灵了,很奇怪。我用的是每秒中断苏醒一次,感觉STM32用起来没其他芯片顺。
icecut 发表于 2014-5-9 10:06 | 显示全部楼层
我怀疑你吧adc时钟之类的搞停了..不在转换,当然没有中断
yu515301489 发表于 2015-8-17 09:52 | 显示全部楼层
不要忘记清中断 配置好唤醒的触发
yangchao1117yc 发表于 2015-12-23 23:17 | 显示全部楼层
wilson970 发表于 2014-5-8 20:05
我调了一个RTC ALARM 唤醒,发现简单测试可以运行很好,但当程序开始执行大量的任务就老是不灵了,很奇怪。 ...

你好,有例程 stm32 睡眠唤醒 例程么,分享下。
yushan210 发表于 2016-1-7 13:30 | 显示全部楼层
jjjkkk00 发表于 2016-1-7 13:50 | 显示全部楼层
找了一下,我这边只有以前测试用的《待机模式》 和《停止模式》的代码。
将就的参考下吧,年代比较久远了。呵呵
  1. /**
  2.   ******************************************************************************
  3.   * [url=home.php?mod=space&uid=288409]@file[/url] /PWR_STANDBY.h
  4.   * [url=home.php?mod=space&uid=187600]@author[/url]    xd.wu
  5.   * [url=home.php?mod=space&uid=895143]@version[/url]   V1.0
  6.   * [url=home.php?mod=space&uid=212281]@date[/url]     2012-4-19
  7.   * [url=home.php?mod=space&uid=247401]@brief[/url]    PWR:待机模式
  8.   WFE事件  新来的中断、之前悬起的中断等(比较容易唤醒)
  9.   WFI中断  
  10.   ******************************************************************************
  11.   *用途:
  12.   3.待机模式:可实现系统的最低功耗
  13.     进入:
  14.       设置CM3系中的SLEEPDEEP位 , PWR_CR中设置PDDS位 , CWUF位
  15.       然后执行WFI(等待中断)或WFE(等待事件)指令
  16.     唤醒:WKUP引脚的上升沿、RTC闹钟事件、NRST引脚上的外部复位、IWDG复位
  17.     唤醒延时:复位阶段时电压调节器的启动

  18.   SCB->SCR[4:0] == SEVONPEND,0,SLEEPDEEP,SLEEPONEXIT,0
  19.   */
  20.   /*实例应用步骤:
  21.   //1."main.cpp"调用fmain()
  22.   
  23.   //2."stm32f10x_it.cpp"拷贝
  24.   void SysTick_Handler(void)
  25.   {
  26.     #if defined __PWR_STANDBY
  27.       GPIO_WriteBit(GPIOF, GPIO_Pin_6, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOF, GPIO_Pin_6)));
  28.     #endif
  29.   }
  30.   void EXTI15_10_IRQHandler(void)
  31.   {
  32.     if(EXTI_GetITStatus(EXTI_Line11) != RESET)
  33.     {
  34.       #if defined __PWR_STANDBY
  35.         GPIO_SetBits(GPIOF, GPIO_Pin_6);
  36.         RTC_ClearFlag(RTC_FLAG_SEC);
  37.         while(RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET);// Wait till RTC Second event occurs
  38.         RTC_SetAlarm(RTC_GetCounter()+ 3);// Set the RTC Alarm after 3s
  39.         RTC_WaitForLastTask();
  40.         //PWR_EnterSTANDBYMode();
  41.         SCB->SCR |= 0x00000004;//SLEEPDEEP = 1
  42.         PWR->CR |= 0x006;//PWR_CR中设置PDDS位 , CWUF位
  43.         __WFE();
  44.       #endif
  45.       EXTI_ClearITPendingBit(EXTI_Line11);
  46.     }
  47.   }
  48.   
  49.   //3."stm32f10x_it.h"声明
  50.   #define __PWR_STANDBY
  51.   void EXTI15_10_IRQHandler(void);
  52.   void SysTick_Handler(void);
  53.   
  54.   //4.Watch中观察
  55.   LED绿灯闪烁
  56.   按下Sel后进入待机模式,3s后RTC闹钟唤醒,黄灯点亮
  57.   */

  58. #ifndef __PWR_STANDBY_H
  59. #define __PWR_STANDBY_H
  60. /* Includes ------------------------------------------------------------------*/
  61. #include "std32periph.h"

  62. /* Private typedef -----------------------------------------------------------*/
  63. /* Private define ------------------------------------------------------------*/
  64.   #define GPIO_LED      GPIOF   
  65.   #define RCC_LED       RCC_APB2Periph_GPIOF
  66.   #define RCC_EXTI      RCC_APB2Periph_GPIOB
  67. /* Private macro -------------------------------------------------------------*/
  68. /* Private variables ---------------------------------------------------------*/
  69. /* Private functions ---------------------------------------------------------*/

  70. void RTC_Configuration(void)
  71. {
  72.   if(PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)/* System resumed from STANDBY mode */
  73.   {
  74.    
  75.     GPIO_SetBits(GPIO_LED, GPIO_Pin_7);

  76.     /* Clear StandBy flag */
  77.     PWR_ClearFlag(PWR_FLAG_SB);

  78.     RTC_WaitForSynchro();
  79.   }
  80.   else
  81.   {
  82.     /* StandBy flag is not set */
  83.     /* RTC clock source configuration ----------------------------------------*/
  84.     BKP_DeInit();
  85.   
  86.     RCC_LSEConfig(RCC_LSE_ON);
  87.     while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  88.     {
  89.     }

  90.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  91.     RCC_RTCCLKCmd(ENABLE);

  92.     /* RTC configuration -----------------------------------------------------*/
  93.     RTC_WaitForSynchro();
  94.     /* Set the RTC time base to 1s */
  95.     RTC_SetPrescaler(32767);  
  96.     RTC_WaitForLastTask();
  97.   }
  98. }

  99. void fmain(void)
  100. {
  101.   RCC_HSEConf(9);//72M
  102.   
  103.   RCC_APB2PeriphClockCmd(RCC_EXTI | RCC_LED | RCC_APB2Periph_AFIO, ENABLE);
  104.   
  105.   GPIO_InitTypeDef GPIO_InitStructure;
  106.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  107.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  108.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  109.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);

  110.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  111.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  112.   GPIO_Init(GPIOB, &GPIO_InitStructure);  

  113.   GPIO_SetBits(GPIO_LED, GPIO_Pin_6);
  114.   
  115.   
  116.   /* Enable PWR and BKP clock */
  117.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  118.   /* Enable WKUP pin */
  119.   PWR_WakeUpPinCmd(ENABLE);
  120.   /* Allow access to BKP Domain */
  121.   PWR_BackupAccessCmd(ENABLE);

  122.   /* Configure RTC clock source and prescaler */
  123.   RTC_Configuration();

  124.   /* Configure EXTI Line to generate an interrupt on falling edge */
  125.   GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);
  126.   EXTI_InitTypeDef EXTI_InitStructure;
  127.   EXTI_InitStructure.EXTI_Line = EXTI_Line11;
  128.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  129.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  130.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  131.   EXTI_Init(&EXTI_InitStructure);  

  132.   NVIC_GroupSet(NVIC_PriorityGroup_0, EXTI15_10_IRQn, 1);

  133.   /* Configure SysTick to generate an interrupt each 250ms */
  134.   SysTick->LOAD = 250000*9;
  135.   SysTick->VAL = 0x00;//清空计数器
  136.   /* ---------------------------------------------------------------------
  137.   SysTick 控制与状态寄存器的位
  138.   SysTick->CTRL: CountFlag【16】,CLKSource【2】,TickINT【1】,ENABLE【0】
  139.   --------------------------------------------------------------------- */
  140.   //CLKSource【2】=0  使用外部时钟源HCLK(1:内核时钟HCLK/8)
  141.   //  TickINT【1】=0  向下计数至0,不会挂起Systick(1:至0会挂起Systick)
  142.   //   ENABLE【0】=0  禁止计数器(1:使能,至0将CountFlag置1)
  143.   SysTick->CTRL = 0x00003;
  144. }

  145. #endif
  146. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
jjjkkk00 发表于 2016-1-7 13:51 | 显示全部楼层
下面这个是STOP模式。
  1. /**
  2.   ******************************************************************************
  3.   * @file /PWR_STOP.h
  4.   * @author    xd.wu
  5.   * @version   V1.0
  6.   * @date     2012-4-19
  7.   * @brief    PWR:停机模式
  8.   WFE事件  新来的中断、之前悬起的中断等(比较容易唤醒)
  9.   WFI中断  
  10.   ******************************************************************************
  11.   *用途:
  12.   2.停机模式
  13.     进入:
  14.       设置CM3中的SLEEPDEEP位 , PWR_CR中清除PDDS位 , 设置LPDS位
  15.       然后执行WFI(等待中断)或WFE(等待事件)指令
  16.     唤醒:任意外部中断可唤醒
  17.     唤醒延时:HSI RC唤醒时间 + 电压调节器从低功耗唤醒的时间

  18.   SCB->SCR[4:0] == SEVONPEND,0,SLEEPDEEP,SLEEPONEXIT,0
  19.   */
  20.   /*实例应用步骤:
  21.   //1."main.cpp"调用fmain()
  22.   
  23.   //2."stm32f10x_it.cpp"拷贝
  24.   #ifdef  __PWR_STOP
  25.   void RTCAlarm_IRQHandler(void)
  26.   {
  27.     if(RTC_GetITStatus(RTC_IT_ALR) != RESET)
  28.     {
  29.       GPIO_WriteBit(GPIOF, GPIO_Pin_8, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOF, GPIO_Pin_8)));
  30.   
  31.       EXTI_ClearITPendingBit(EXTI_Line17);
  32.   
  33.       if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)
  34.       {
  35.         PWR_ClearFlag(PWR_FLAG_WU);
  36.       }
  37.   
  38.       RTC_WaitForLastTask();   
  39.   
  40.       RTC_ClearITPendingBit(RTC_IT_ALR);
  41.   
  42.       RTC_WaitForLastTask();
  43.     }
  44.   }
  45.   #endif
  46.   
  47.   //3."stm32f10x_it.h"声明
  48.   #define __PWR_STOP
  49.   void RTCAlarm_IRQHandler(void);
  50.   
  51.   //4.Watch中观察
  52.   LED绿灯变化
  53.   进入停机模式,3s后RTC闹钟唤醒,红灯点亮,循环
  54.   */

  55. #ifndef __PWR_STOP_H
  56. #define __PWR_STOP_H
  57. /* Includes ------------------------------------------------------------------*/
  58. #include "std32periph.h"

  59. /* Private typedef -----------------------------------------------------------*/
  60. /* Private define ------------------------------------------------------------*/
  61.   #define GPIO_LED      GPIOF   
  62.   #define RCC_LED       RCC_APB2Periph_GPIOF
  63. /* Private macro -------------------------------------------------------------*/
  64. /* Private variables ---------------------------------------------------------*/
  65. /* Private functions ---------------------------------------------------------*/

  66. void SYSCLKConfig_STOP(void)
  67. {
  68.   /* Enable HSE */
  69.   RCC_HSEConfig(RCC_HSE_ON);

  70.   /* Wait till HSE is ready */
  71.   ErrorStatus HSEStartUpStatus;
  72.   HSEStartUpStatus = RCC_WaitForHSEStartUp();

  73.   if(HSEStartUpStatus == SUCCESS)
  74.   {
  75.     /* Enable PLL */
  76.     RCC_PLLCmd(ENABLE);

  77.     /* Wait till PLL is ready */
  78.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  79.     {
  80.     }

  81.     /* Select PLL as system clock source */
  82.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  83.     /* Wait till PLL is used as system clock source */
  84.     while(RCC_GetSYSCLKSource() != 0x08)
  85.     {
  86.     }
  87.   }
  88. }

  89. void RTC_Configuration(void)
  90. {
  91.   /* RTC clock source configuration ------------------------------------------*/
  92.   /* Reset Backup Domain */
  93.   BKP_DeInit();
  94.   
  95.   /* Enable the LSE OSC */
  96.   RCC_LSEConfig(RCC_LSE_ON);
  97.   /* Wait till LSE is ready */
  98.   while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  99.   {
  100.   }

  101.   /* Select the RTC Clock Source */
  102.   RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

  103.   /* Enable the RTC Clock */
  104.   RCC_RTCCLKCmd(ENABLE);

  105.   /* RTC configuration -------------------------------------------------------*/
  106.   /* Wait for RTC APB registers synchronisation */
  107.   RTC_WaitForSynchro();

  108.   /* Set the RTC time base to 1s */
  109.   RTC_SetPrescaler(32767);  
  110.   /* Wait until last write operation on RTC registers has finished */
  111.   RTC_WaitForLastTask();

  112.   /* Enable the RTC Alarm interrupt */
  113.   RTC_ITConfig(RTC_IT_ALR, ENABLE);
  114.   /* Wait until last write operation on RTC registers has finished */
  115.   RTC_WaitForLastTask();
  116. }


  117. void fmain(void)
  118. {
  119.   RCC_HSEConf(9);//72M
  120.   
  121.   RCC_APB2PeriphClockCmd(RCC_LED | RCC_APB2Periph_AFIO, ENABLE);
  122.   
  123.   GPIO_InitTypeDef GPIO_InitStructure;
  124.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_8;
  125.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  126.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  127.   GPIO_Init(GPIO_LED, &GPIO_InitStructure);


  128.   /* Configure EXTI Line17(RTC Alarm) to generate an interrupt on rising edge */
  129.   EXTI_ClearITPendingBit(EXTI_Line17);
  130.   EXTI_InitTypeDef EXTI_InitStructure;
  131.   EXTI_InitStructure.EXTI_Line = EXTI_Line17;
  132.   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  133.   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  134.   EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  135.   EXTI_Init(&EXTI_InitStructure);

  136.   
  137.   /* Enable PWR and BKP clock */
  138.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  139.   /* Allow access to BKP Domain */
  140.   PWR_BackupAccessCmd(ENABLE);
  141.   /* Configure RTC clock source and prescaler */
  142.   RTC_Configuration();


  143.   NVIC_GroupSet(NVIC_PriorityGroup_0, RTCAlarm_IRQn, 0);

  144.   GPIO_SetBits(GPIO_LED, GPIO_Pin_6);
  145.   
  146.   while (1)
  147.   {
  148.     /* Insert 1.5 second delay */
  149.     Delay_us(1.5e6, 72);

  150.    
  151.     RTC_ClearFlag(RTC_FLAG_SEC);
  152.     while(RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET);

  153.     RTC_SetAlarm(RTC_GetCounter()+ 3);
  154.     RTC_WaitForLastTask();


  155.     GPIO_ResetBits(GPIO_LED, GPIO_Pin_6);


  156.     //PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
  157.     RCC->APB1ENR |= 0x10000000;//PWREN:电源接口时钟使能
  158.     SCB->SCR |= 0x00000004;//SLEEPDEEP = 1
  159.     PWR->CR &= 0x1FD;//PWR_CR中清除PDDS位 , 设置LPDS位
  160.     PWR->CR |= 0x001;
  161.     __WFI();
  162.    

  163.     GPIO_SetBits(GPIO_LED, GPIO_Pin_6);

  164.     SYSCLKConfig_STOP();
  165.   }
  166. }

  167. #endif
  168. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
jjjkkk00 发表于 2016-1-7 13:55 | 显示全部楼层
顺便说下,当时的测试环境是STM32F103E的万利开发板。
测试功能可用。实际应用时建议对代码优化。
小小飞行器 发表于 2016-1-23 17:37 | 显示全部楼层
现在有睡眠模式的好东西吗??不妨分享一下
dongnanxibei 发表于 2016-1-30 11:30 | 显示全部楼层
睡眠模式 对应 SLEEP
停止模式 对应 STOP
待机模式 对应 Standby
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

10

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部