有人玩过STM32F0的停机唤醒么?我的怎么唤不醒呢?

2019-08-19 20:19发布

本帖最后由 xiong2088 于 2016-10-7 10:42 编辑

我用的单片机是stm32f051,要求串口和按键唤醒,那待机模式是不能用了,只能用停机模式。开始只是在唤醒中断里简单地进行软复位,那现在我想唤醒到原来的状态,根据手册,我在中断里清中断标志后,再运行SystemInit(),然后打开各个外设时钟,可是唤不醒。后来在网上查了资料,说要在中断里清除所有可能的中断标志位,还是不能唤醒。请使用过停机模式的大虾们指导指导!
请不要用待机模式来说停机模式,两者差别太大了。

代码:
外部中断服务函数:
void EXTI4_15_IRQHandler(void)
{
        if(EXTI_GetITStatus(EXTI_Line7) != RESET)                //过零检测,这是外部中断--------这部分可以正常工作。
        {       
                EXTI_ClearITPendingBit(EXTI_Line7);
                TIM_Cmd(TIM6, ENABLE);               
        }
       
        if(EXTI_GetITStatus(EXTI_Line13) != RESET)        //按键唤醒
        {       
                EXTI_ClearITPendingBit(EXTI_Line13);
                EXTI_ClearITPendingBit(EXTI_Line7);

                TIM_ClearFlag(TIM6,TIM_IT_Update);
                USART_ClearITPendingBit(USART1, USART_IT_RXNE);
               
                if (PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)
                {
                        PWR_ClearFlag(PWR_FLAG_WU);
                }
                Quit_LowPower_manage();                                                                                                                                //
        }
}

void Quit_LowPower_manage(void)
{
//        delay_ms(25);                                //
        SystemInit();
//        delay_ms(100);
       
        RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE);
        RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOB, ENABLE);
        RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOC, ENABLE);
        RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOF, ENABLE);
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
       
        RCC_HSI14Cmd(ENABLE);
        while (RCC_GetFlagStatus(RCC_FLAG_HSI14RDY) == RESET);
        ADC_Cmd(ADC1, ENABLE);
       
        TIM_Cmd(TIM6, ENABLE);
       
        Exti7_Config();    //过零检测的功能需要恢复,因为在进入停机模式前已经关闭,以免唤醒单片机。
        Quit_WkupExti13();        //PC13的唤醒功能丧失,变成了按键。因为在进入停机模式前使能了外部中断唤醒的功能。
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
xiong2088
1楼-- · 2019-08-20 01:11
已经搞定了,分应该给我自己吧。
csmjmcc
2楼-- · 2019-08-20 01:40
/*******************************************************************************
* Function Name  : PWR_EnterSTOPMode
* Description    : Enters STOP mode.
* Input          : - PWR_Regulator: specifies the regulator state in STOP mode.
*                    This parameter can be one of the following values:
*                       - PWR_Regulator_ON: STOP mode with regulator ON
*                       - PWR_Regulator_LowPower: STOP mode with
*                         regulator in low power mode
*                  - PWR_STOPEntry: specifies if STOP mode in entered with WFI or
*                    WFE instruction.
*                    This parameter can be one of the following values:
*                       - PWR_STOPEntry_WFI: enter STOP mode with WFI instruction
*                       - PWR_STOPEntry_WFE: enter STOP mode with WFE instruction
* Output         : None
* Return         : None
*******************************************************************************/
void PWR_EnterSTOPMode(u32 PWR_Regulator, u8 PWR_STOPEntry)          //进入停止(STOP)模式 -csm note
{
  u32 tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_PWR_REGULATOR(PWR_Regulator));
  assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
  
  /* Select the regulator state in STOP mode ---------------------------------*/
  tmpreg = PWR->CR;                //电源控制寄存器 -csm note

  /* Clear PDDS and LPDS bits */
  /************************************************************************
                PDDS:掉电深睡眠
                        与LPDS位协同操作
                        0:当CPU进入深睡眠时进入停机模式,调压器的状态由LPDS位控制。
                        1:CPU进入深睡眠时进入待机模式。
                LPDS:深睡眠下的低功耗
                        PDDS=0时,与PDDS位协同操作
                        0:在停机模式下电压调压器开启
                        1:在停机模式下电压调压器处于低功耗模式       
  ***********************************************************************/
  tmpreg &= CR_DS_Mask;

  /* Set LPDS bit according to PWR_Regulator value */
  tmpreg |= PWR_Regulator;

  /* Store the new value */
  PWR->CR = tmpreg;

  /* Set SLEEPDEEP bit of Cortex System Control Register */
  /* 设置Stop或Standby的标记 -csm note 注意:网上说此标志位若非STOP,则务必在唤醒时清除!*/
  *(vu32 *) SCB_SysCtrl |= SysCtrl_SLEEPDEEP_Set;
  
  /* Select STOP mode entry --------------------------------------------------*/
  if(PWR_STOPEntry == PWR_STOPEntry_WFI)
  {   
    /* Request Wait For Interrupt */
    __WFI();
  }
  else
  {
    /* Request Wait For Event */
    __WFE();
  }
}

/*************************************************************
功能:从停止模式退出时的时钟配置。
输入:无
输出:无
*************************************************************/
void RCC_EXITSTOP(void)
{
        RCC_PLLCmd(ENABLE);
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
        {
        }
        /* Select PLL as system clock source */
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
       
        /* Wait till PLL is used as system clock source */
        while(RCC_GetSYSCLKSource() != 0x08)
        {
        }
}

for(; ;)
{
         PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
         RCC_EXITSTOP();       
}
xiong2088
3楼-- · 2019-08-20 05:49
本帖最后由 xiong2088 于 2016-10-7 10:22 编辑
csmjmcc 发表于 2016-10-7 09:57
/*******************************************************************************
* Function Name  : ...

void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
{
  uint32_t tmpreg = 0;
  
  /* Check the parameters */
  assert_param(IS_PWR_REGULATOR(PWR_Regulator));
  assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
  
  /* Select the regulator state in STOP mode ---------------------------------*/
  tmpreg = PWR->CR;
  /* Clear PDDS and LPDSR bits */
  tmpreg &= CR_DS_MASK;
  
  /* Set LPDSR bit according to PWR_Regulator value */
  tmpreg |= PWR_Regulator;
  
  /* Store the new value */
  PWR->CR = tmpreg;
  
  /* Set SLEEPDEEP bit of Cortex-M0 System Control Register */
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  
  /* Select STOP mode entry --------------------------------------------------*/
  if(PWR_STOPEntry == PWR_STOPEntry_WFI)
  {
    /* Request Wait For Interrupt */
    __WFI();
    /* Reset SLEEPDEEP bit of Cortex System Control Register */
    SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);                   //这里已经清除了。
  }
  else if (PWR_STOPEntry == PWR_STOPEntry_WFE)
  {
    /* Request Wait For Event */
    __WFE();
    /* Reset SLEEPDEEP bit of Cortex System Control Register */
    SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);   
  }
  else
  {
    /* Set SLEEP on exit bit of Cortex-M0 System Control Register */
    SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
  }
}
xiong2088
4楼-- · 2019-08-20 10:46
 精彩回答 2  元偷偷看……
ceshi3314
5楼-- · 2019-08-20 15:14
xiong2088 发表于 2017-4-12 17:04
睡眠模式没玩过。

楼主 你好,STOP  RTC 的代码 可以 共享一下吗?  我调试了好长时间 还是 不行,每次唤醒后 串口 打印输出都出错
ceshi3314
6楼-- · 2019-08-20 17:37
xiong2088 发表于 2017-4-12 17:04
睡眠模式没玩过。

QQ3314900970  非常感谢

一周热门 更多>