10351|8

15

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

关于STM32休眠不能唤醒的问题,附代码 [复制链接]

stop_mode:
                                            #if DEBUG
                                            printf("MCU Enter Stop Mode!\n");
                                            #endif
                                           
                                            //set the all GPIO as general GPIO 、remap IRDA in EXIT0 and disable TIM4 interrupt
                                            lowLevelGPIOCfg();  //将一些GPIO打到低电平,避免休眠耗电

                        ADC_Cmd(ADC1, DISABLE);//关闭ADC
                        DMA_Cmd(DMA1_Channel1, DISABLE);//关闭DMA
                        WireControl_EXTI_Enable();                        //配置一个外部中断

                        GPIO_ResetBits(Led_Power, Led_Power_Pin);//关闭电源灯
                                            //GPIO_SetBits(Led_Power, Led_Power_Pin);                                       
                                           
                                            BKP_WriteBackupRegister(BKP_DR3, 0xFFFF);  //设置一个备份寄存器,作为复位之后的判断标志
                                           
                                            //Enter a stop mode
                                            //Request to enter STOP mode with regulator in low power mode, wake by any exit interrupt
                                            IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);//看门狗计数器访问使能
                                            IWDG_SetReload(0xfff);//设置看门狗重载值,由原来的3秒,改为26秒
                                            IWDG_ReloadCounter();//装载看门狗计数器
                                           
                                        PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);//进入停止模式

                                            //以下是唤醒之后的配置操作       
                                            reconfigSysClkConfig();        //重新配置系统时钟
                                   
                                              NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
                                              NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
                                              NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
                                              NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
                                              NVIC_Init(&NVIC_InitStructure);//

                                              //Configure EXTI0 line
                                              EXTI_InitStructure.EXTI_Line = EXTI_Line0;
                                              EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
                                              EXTI_InitStructure.EXTI_Trigger = ACC_EXTI_Trigger ;   
                                            EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising ;   
                                              EXTI_InitStructure.EXTI_LineCmd = DISABLE;
                                              EXTI_Init(&EXTI_InitStructure);

                        WireControl_EXTI_Disable();
           
                                            //restore the GPIO configurate
                                            GPIO_Configuration(0);
                                            GPIO_SetBits(Led_Power, Led_Power_Pin);
                                            USART_Configuration();
                                            NVIC_Configuration();
                                            TIM_Configuration();
                                            TIM_ITConfig(TIM2, TIM_IT_Update , DISABLE);//开启计数中断
                                            DMA_Configuration();
                                            ADC_Configuration();

                                            BKP_WriteBackupRegister(BKP_DR3, 0x0000);//修改备份寄存器的值
                                            IWDG_Config();
                                            SysTick_Config(SystemCoreClock / 5);
                    }
本人解释一下大体代码思路,进入休眠之后,会拉低相关的GPIO,确保省电;配置一些外部中断,用来唤醒停止模式;休眠前写入一个值到备份寄存器。
然后休眠,休眠26秒后,看门狗复位,程序重启,判断是否由看门够引起的复位(第一次肯定是由看门够引起的复位,因为备份寄存器里面有休眠之前写入的值),若是由看门狗引起的复位,则不会开启看门狗功能,直接再次进入到这段代码,再次进入休眠,这次休眠,因为没有看门狗,所以可以一直休眠下去(只要没有外部中断触发),当外部中断触发以后,程序就唤醒,之后修改备份寄存器里面的值。
以下是问题:
      个人倒是觉得代码和思路都没问题。但是测试的时候发现一个问题。而且是概率性的。
      偶尔进入停止模式的时候,我的所有外部中断都无法将其唤醒。非要等复位过后,再次进入停止模式,才能由
      外部中断唤醒。这真的是让我蛋碎了一地。。
看各位有啥高见。

此帖出自stm32/stm8论坛

最新回复

这倒是个问题,晚上我测试一下这个代码  详情 回复 发表于 2015-9-6 13:32
点赞 关注
 

回复
举报

466

帖子

0

TA的资源

版主

沙发
 
我也没搞过休眠,你的意思只能唤醒一次,那这样的话应该是唤醒后初始化有问题啊,才会导致不会再次进入啊。
此帖出自stm32/stm8论坛
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
第一次进入休眠后,有概率无法被外部中断唤醒(我配置的所有的外部中断)
此帖出自stm32/stm8论坛

点评

http://bbs.elecfans.com/forum.php?mod=viewthread&tid=464288&extra=  详情 回复 发表于 2015-8-25 10:19
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

4
 
stop_mode:
                                            #if DEBUG
                                            printf("MCU Enter Stop Mode!\n");
                                            #endif
//本人测试发现,在这里加上
RTC_Configuration();
//则可以避免该现象
                                          
                                            //set the all GPIO as general GPIO 、remap IRDA in EXIT0 and disable TIM4 interrupt
                                            lowLevelGPIOCfg();  //将一些GPIO打到低电平,避免休眠耗电

                        ADC_Cmd(ADC1, DISABLE);//关闭ADC


其中函数定义:
void RTC_Configuration(void)
{

       

       
        // Allow access to BKP Domain
        PWR_BackupAccessCmd(ENABLE);

        // Reset Backup Domain
        //BKP_DeInit();

        // Enable LSE
        RCC_LSEConfig(RCC_LSE_ON);
        // Wait till LSE is ready
        while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
        {
        }

        // Select LSE as RTC Clock Source
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

        // Enable RTC Clock
        RCC_RTCCLKCmd(ENABLE);

        // Wait for RTC registers synchronization
        RTC_WaitForSynchro();

        // Wait until last write operation on RTC registers has finished
        RTC_WaitForLastTask();

        // Enable the RTC Alarm
        //RTC_ITConfig(RTC_IT_ALR, ENABLE);

        // Wait until last write operation on RTC registers has finished
        //RTC_WaitForLastTask();

        // Set RTC prescaler: set RTC period to 1 sec
        // RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1)
        RTC_SetPrescaler(32767);

        // Wait until last write operation on RTC registers has finished
        RTC_WaitForLastTask();

        //GPS复用PC13
        BKP_TamperPinCmd(DISABLE);  //关闭入侵检测功能,也就是 PC13,也可以当普通IO使用
        BKP_ITConfig(DISABLE);
}

但是函数里面存在备份寄存器的复位,会丢掉所有备份寄存器的值,唉,其实不知道根本原因在哪里
此帖出自stm32/stm8论坛
 
 
 

回复

466

帖子

0

TA的资源

版主

5
 
传承剑圣 发表于 2015-8-25 01:18
第一次进入休眠后,有概率无法被外部中断唤醒(我配置的所有的外部中断)


 

此帖出自stm32/stm8论坛

点评

帅锅,我用的是停止模式 PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);//进入停止模式  详情 回复 发表于 2015-9-6 11:40
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

6
 


帅锅,我用的是停止模式
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);//进入停止模式

此帖出自stm32/stm8论坛
 
 
 

回复

918

帖子

0

TA的资源

纯净的硅(中级)

7
 
这倒是个问题,晚上我测试一下这个代码
此帖出自stm32/stm8论坛
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

8
 
其实,代码单独抠出来,测试应该是没有问题的。
可能跟我的工程有关。
业务上是这样的,
在程序正常运行的时候,红外接收头的GPIO被定义为定时器捕获的输入,红外POWER键长按5秒之后关机,
在关机之前,将红外接收头的GPIO配置为外部中断(因为停止模式只能由外部中断唤醒或者RTC、USB等唤醒)
然后休眠后,就可以由红外信号唤醒MCU,唤醒后再把红外接收头的GPIO被定义为定时器捕获的输入。
为什么有时候唤不醒,个人推测原因:
在红外POWER键长按的时候,定时器捕获中断一直在触发,当确定收到POWER键长按5秒信号之后关机。
但是手不一定会立刻放开POWER键,所以定时器捕获中断一直在触发,但是在这个时候,我们又在重新配置
红外接收头的GPIO,EXTI,NVIC。所以我推测这里出现了问题。说简单一点就是,在中断函数不断触发的同时
我们在配置它的中断模式,NVIC,这样导致了矛盾。
这只是我的推测,不知大家有何看法。
另外加一条,在我实验的时候发现,虽然在休眠,但是可以响应外部中断(会执行中断服务函数),但就是唤不醒
此帖出自stm32/stm8论坛
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

9
 
其实个人也做了规避措施,做法是这样的。
红外POWER键长按5秒关机之后,我会关闭定时器不再捕获红外信号,然后延时300ms,
然后再来配置红红外接收头的GPIO,EXTI,NVIC,这样就没有出现那个现象了。
但是这只是一个规避措施,还是不知道为什么会发生那样的现象。真是如鲠在喉啊
看大家有无想法。
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表