PA0唤醒和RTC唤醒

2019-07-20 03:33发布

楼主需要做两个方式的待机唤醒实验,用的是stm32 F103,初步想达到的实验结果是PA0中断唤醒和RTC闹钟唤醒互相切换:

PA0唤醒后,系统跑一个流程后设置为RTC闹钟唤醒,并将PA0唤醒屏蔽;
RTC闹钟唤醒后,系统跑一个流程后设置为PA0唤醒,不用闹钟唤醒或者将闹钟设置的时间变长;

用到的是原子的例程,函数也是从原子里参考过来的:
发现的问题是PA0单独唤醒和RTC闹钟单独唤醒都是OK的,我在实验中利用了BKP寄存器来保存上一次醒来的方式做判断来切换,
问题是当一次PA0唤醒后,进入待机模式以后,PA0唤醒一直存在,不重启就一直存在,把相应的位禁掉之后不起作用。不知道为什么,代码如下:
                                                                       /*取消备份区写保护*/
                                                                        RCC->APB1ENR|=1<<28;     //使能电源时钟            
                                                                        RCC->APB1ENR|=1<<27;     //使能备份时钟       
                                                                        PWR->CR|=1<<8;           //取消备份区写保护
                                                                        delay_ms(100);

                                                                    /*****读取上次的唤醒方式*********/
                                                                  WKUPMod = BKP_ReadBackupRegister(BKP_DR5);
                                                                      delay_ms(100);
                                                              //***********************************                                                       
        if(WKUPMod==1)//PA0唤醒
        {
                       
                PWR->CSR|=0<<8;                                                            //不设置WKUP用于唤醒               
                BKP_WriteBackupRegister(BKP_DR5,(uint16_t)2);                  //写BKP寄存器
                DelayMod=30;
                RTC_Init();                                  //RTC初始化
                while(RTC_Init())                //RTC初始化        ,一定要初始化成功
            {
                delay_ms(800);
            }               
           rtccnt=RTC->CNTH;//得到闹钟值
           rtccnt<<=16;
           rtccnt|=RTC->CNTL;                                       
           ALARM_CNT_Set(rtccnt+DelayMod);//设置30秒钟后,闹钟唤醒
               
        }
        else//RTC唤醒
        {
               
                PWR->CSR|=1<<8;//设置WKUP用于唤醒
                BKP_WriteBackupRegister(BKP_DR5,(uint16_t)1);               
        }
                       

                                GPIO_ResetBits(GPIOB, PB14);
                                delay_ms(2000);                                               
                                Sys_Enter_Standby();



-------------------------------------------------------------------------------------------------------------------
void Sys_Enter_Standby(void)
{                         
        //关闭所有外设(根据实际情况写)
           RCC->APB2RSTR|=0X01FC;//复位所有IO口
        //关闭所有用到的时钟----串口2NB口
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,DISABLE);
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,DISABLE);
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,DISABLE);
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, DISABLE);
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);
       
       
        Sys_Standby();//进入待机模式
}

---------------------------------------------------------------------------------------------------

//进入待机模式          
void Sys_Standby(void)
{
        SCB->SCR|=1<<2;//使能SLEEPDEEP位 (SYS->CTRL)
       
                /*取消备份区写保护*/
                                                                        RCC->APB1ENR|=1<<28;     //使能电源时钟            
                                                                        RCC->APB1ENR|=1<<27;     //使能备份时钟       
                                                                        PWR->CR|=1<<8;           //取消备份区写保护
                                                                        delay_ms(100);
        PWR->CR|=1<<2;           //清除Wake-up 标志
        PWR->CR|=1<<1;           //PDDS置位                  
        WFI_SET();                                 //执行WFI指令                 
}       

---------------------------------------------------------------------------------------------------------------------------------
//中断处理函数,清标志即可
void EXTI0_IRQHandler(void)
{                                                                                                  
         
        EXTI->PR=1<<0;  //清除LINE10上的中断标志位
}

---------------------------------------------------------------------------------------------------------------------------


实验现象是:当板子因为RTC闹钟进入待机后,将PA0短接3.3v,然后松开,会启动板子,然后再次进入待机,此时按照我写的程序来说,PA0唤醒应该已经不起作用了,但是此时再次短接PA0和3.3v,板子又会起来,也就是说
PA0启动一次后像记住了一样,一直存在。按下复位键再次启动程序,PA0恢复正常,无法唤醒板子,唤醒一次后,又杀不掉这个唤醒方法了。         


求大神解释下是什么原因。


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
叮叮蛋炒饭
1楼-- · 2019-07-20 05:39
 精彩回答 2  元偷偷看……
正点原子
2楼-- · 2019-07-20 08:23
帮顶
叮叮蛋炒饭
3楼-- · 2019-07-20 09:31
 精彩回答 2  元偷偷看……
叮叮蛋炒饭
4楼-- · 2019-07-20 12:24
有没有大神做过类似的实验,求助啊

一周热门 更多>