打印

stm32l低功耗退出问题

[复制链接]
16991|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 liaoyijiaren 于 2013-6-17 20:09 编辑

本人初弄stm32l,最近改了官方开发板的例程,让MCU进入低功耗运行模式后自自行退出低功耗模式,但悲催的是进入低功耗模式后(测的低功耗运行模式只有6uA电流),但是无法退出低功耗模式,求大神指导!
还有一直不明白其进入其它低功耗模式后怎么退出(即退出后程序从哪开始运行),
    /* Set IO in lowpower configuration*/
    GPIO_LowPower_Config(); //跟我设想的一样,在进行低功耗模式下把所有的邋IO引脚都设为模拟输入,降低功耗。
    /*Disable fast wakeUp*/
    PWR_FastWakeUpCmd(ENABLE);

     /* Disable PVD */
    PWR_PVDCmd(DISABLE);

    /* Enable The ultra Low Power Mode  VREFINT is switched off in low power mode*/
    PWR_UltraLowPowerCmd(ENABLE);     //不明此函数意思

    /* Save the RCC configuration registers */
    Config_RCC(&SavRCC);      
   
    /* Stop the sys tick in order to avoid IT */
    SysTick->CTRL = 0;
    SetHSICLKToMSI(RCC_MSIRange_0,DIV2,NoRTC) ;

    PWR_EnterLowPowerRunMode(ENABLE);//此句是关键呀,现在的问题是怎么从低功耗模式出来。
    while(PWR_GetFlagStatus(PWR_FLAG_REGLP) == RESET) ;

    disableInterrupts();            
    EnterLPRUNModeRAM();//此处不明白只知道绝大部分电流是通过此函数关掉的。
    enableInterrupts();        

     for (i=0;i<0x1f0;i++)//适当延时后退出低功耗运行模式
    {
      __NOP();  __NOP();    __NOP();  __NOP();
      __NOP();  __NOP();    __NOP();  __NOP();
      __NOP();  __NOP();    __NOP();  __NOP();
      __NOP();  __NOP();    __NOP();  __NOP();
      __NOP();  __NOP();    __NOP();  __NOP();
      __NOP();  __NOP();    __NOP();  __NOP();
      __NOP();  __NOP();    __NOP();  __NOP();
      __NOP();  __NOP();    __NOP();  __NOP();
      __NOP();  __NOP();    __NOP();  __NOP();
      __NOP();  __NOP();    __NOP();  __NOP();
      __NOP();  __NOP();    __NOP();  __NOP();
    }   
     PWR_EnterLowPowerRunMode(DISABLE);
     while(PWR_GetFlagStatus(PWR_FLAG_REGLP) != RESET) ;      
     SetHSICLK(); //把HSI打开     Config_Systick();
     RCC->AHBENR = SavRCC.AHBENR;  

     PWR_VoltageScalingConfig(PWR_VoltageScaling_Range1);//VCORE=1.8V
     /* Wait Until the Voltage Regulator is ready */
     while (PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET) ;
     /* To restore RCC registers */
     RCC->APB1ENR = SavRCC.APB1ENR;
     RCC->APB2ENR = SavRCC.APB2ENR;
     RCC->AHBLPENR = SavRCC.AHBLPENR;  
     RCC->APB1LPENR = SavRCC.APB1LPENR;
     RCC->APB2LPENR = SavRCC.APB2LPENR;

     /* Need to reinit RCC for LCD*/
     RCC_Configuration();
     PWR_EnterLowPowerRunMode(DISABLE);

     /* Disable Ultra low power mode */
     PWR_UltraLowPowerCmd(DISABLE);

     /* Disable FLASH during SLeep LP */
     FLASH_SLEEPPowerDownCmd(DISABLE);

     Restore_GPIO_Config();  

     /* Clear Wake Up flag  Clear the WUF Wakeup flag after 2 system clock cycles*/
     PWR_ClearFlag(PWR_FLAG_WU);

     /* Enable PVD */
     PWR_PVDCmd(ENABLE);


沙发
liaoyijiaren|  楼主 | 2013-6-17 19:47 | 只看该作者
求解决方法

使用特权

评论回复
板凳
hkcj| | 2013-6-17 20:30 | 只看该作者
不是很了解这一块   楼主   帮你顶一个   再看看别人的意见吧   顶一个  

使用特权

评论回复
地板
liaoyijiaren|  楼主 | 2013-6-17 20:39 | 只看该作者
hkcj 发表于 2013-6-17 20:30
不是很了解这一块   楼主   帮你顶一个   再看看别人的意见吧   顶一个

恩。谢谢啦。希望大家帮顶下。急

使用特权

评论回复
5
liuje| | 2013-6-17 21:35 | 只看该作者
离开低功耗模式只有3种可能  :
1. 利用时间计时中断唤醒.
2. 利用外部中断输入唤醒.
3. 按了reset键  (这个是废话) .

三种方式都将把从 main() 下的 "第一行"  代码开始运行 .
因此, 如果你要判断是复位还是唤醒,  可以读取电源相关记存器可以判断的出来.
如果你不需要判断,  那就是你没正确的利用以上1,2两点离开待机模式.



使用特权

评论回复
6
liuje| | 2013-6-17 21:50 | 只看该作者

#include <stm32f10x_lib.h>
#include "sys.h"
...................
....................

void EXTI0_IRQHandler(void)
{                                                                                                 
        EXTI->PR=1<<0;        //清除LINE 中断標誌位        , 如果只为了唤醒, 就只要清除此旗标就行了.                
}


void main(void)
{
       ........略1........

        RCC->APB2ENR|=1<<2;      //PORTA時鐘 ENABLE          
        RCC->APB2ENR|=1<<0;      //開啟輔助時鐘                  
       
        GPIOA->CRL&=0XFFFFFFF0;              //PA0設置為輸入          
        GPIOA->CRL|=0X00000008;  
        Ex_NVIC_Config(GPIO_A,0,RTIR);        //PA0上升緣觸發中断      ** 印象中只能使用 "上升缘" 触发来做唤醒                                                                                                                
        MY_NVIC_Init(2,2,EXTI0_IRQChannel,2); //搶佔2, 子優先級2, 組2

       .....略2........
      

        if (PWR->CSR==258)                           // 待機下喚醒, 非RESET   ?   "258"是我单步跟踪得到的值, 就直接拿来用了, 详细可见CSR电源记存器的定义
        {                  
                goto proc2;                                   // 如果是外部中断CPU喚醒,  则跳至proc2处
        }

        ......略3............   

        RCC->APB2RSTR|=0X01FC;  //重設所有I/O口
          RCC->APB2ENR=0;  
        Sys_Standby();          //系統進入Standby狀態       
}

最后,  当进入待机状态后,  如果PA0被触发了(例如接一个按键, 另一脚接到3.3V) ,  CPU就会被唤醒离开待机模式,
唤醒后就会从  "......略1........." (第1行)开始运行,   就相当于复位或重新上电.     差异只是我们可以透过判断电源记存器
得知是否是一个唤醒事件,  然后对应做某些事.      


已经讲的这么详细了,  应该能明白了吧 ?   至于时间定时中断唤醒,  很多网路**说有些小问题, 唤醒时间有长有短, 也不是很容易设置.   您可以自己再TRY看看.







使用特权

评论回复
7
liuje| | 2013-6-17 22:05 | 只看该作者
再送您一个网上找到的参考资料...感谢原作者  !!

stm32功耗测试学习笔记.pdf

647 KB

使用特权

评论回复
8
liuje| | 2013-6-17 22:52 | 只看该作者
完整的离开待机状态的方法 :


使用特权

评论回复
9
wgsxsm| | 2013-6-18 00:12 | 只看该作者
同在做,不过我的项目使用的是STM32F0的片子

使用特权

评论回复
10
liaoyijiaren|  楼主 | 2013-6-18 09:20 | 只看该作者
liuje 发表于 2013-6-17 21:35
离开低功耗模式只有3种可能  :
1. 利用时间计时中断唤醒.
2. 利用外部中断输入唤醒.

你的意思是只要在低功耗期间发生了中断,而不需要在该中断函数里写任何代码,程序就自动从main()开始执行?像重新上电一样?

使用特权

评论回复
11
liaoyijiaren|  楼主 | 2013-6-18 09:42 | 只看该作者
liuje 发表于 2013-6-17 21:50
#include
#include "sys.h"
...................

谢谢你的热心回复,我明白了退出低功耗模式后从哪运行的问题了(因为之前弄过MSP430,它的低功耗退出跟stm32不一样),

使用特权

评论回复
12
IJK| | 2013-6-18 09:49 | 只看该作者
stm32l有多种低功耗模式:
- LowPowerRunMode,LZ用的就是这个模式,电流约几uA,所以LZ的测量结果是对头的。此时CPU还在运行。
- LowPowerWaitMode,电流比上面低点,CPU停止运行。
- STOP mode,电流约0.4uA,唤醒后从下1行执行
- STANDBY mode,电流约0.3uA,唤醒后从复位入口执行

使用特权

评论回复
13
liaoyijiaren|  楼主 | 2013-6-18 10:29 | 只看该作者
IJK 发表于 2013-6-18 09:49
stm32l有多种低功耗模式:
- LowPowerRunMode,LZ用的就是这个模式,电流约几uA,所以LZ的测量结果是对头的 ...

之前看过你的分析,我用的是低功耗运行模式,我设置的是CPU运行一段时间后自行退出 低功耗,但是无法退出呀

使用特权

评论回复
14
IJK| | 2013-6-18 11:51 | 只看该作者
liaoyijiaren 发表于 2013-6-18 10:29
之前看过你的分析,我用的是低功耗运行模式,我设置的是CPU运行一段时间后自行退出 低功耗,但是无法退出 ...

何以见得无法退出?

使用特权

评论回复
15
liaoyijiaren|  楼主 | 2013-6-18 12:58 | 只看该作者
IJK 发表于 2013-6-18 11:51
何以见得无法退出?

我用万能表接里面测电流,显示电流一直为6uA,也无法唤醒

使用特权

评论回复
16
IJK| | 2013-6-18 13:33 | 只看该作者
可以用调试器看代码运行在哪一行。
可以看看函数EnterLPRUNModeRAM() 的退出条件是什么。

使用特权

评论回复
17
liaoyijiaren|  楼主 | 2013-6-18 13:42 | 只看该作者
IJK 发表于 2013-6-18 13:33
可以用调试器看代码运行在哪一行。
可以看看函数EnterLPRUNModeRAM() 的退出条件是什么。 ...

问题在于低功耗模式下无法使用调试器

使用特权

评论回复
18
IJK| | 2013-6-18 16:36 | 只看该作者
liaoyijiaren 发表于 2013-6-18 13:42
问题在于低功耗模式下无法使用调试器

根据Debug support章节进行必要的设置,在低功耗模式下也可以使用调试器,当然这时候功耗比较大

使用特权

评论回复
19
liaoyijiaren|  楼主 | 2013-6-18 16:50 | 只看该作者
IJK 发表于 2013-6-18 16:36
根据Debug support章节进行必要的设置,在低功耗模式下也可以使用调试器,当然这时候功耗比较大 ...

IJK 可以给个相应的代码我吗?    我的邮箱是492319345@qq.com

使用特权

评论回复
20
liaoyijiaren|  楼主 | 2013-6-18 16:54 | 只看该作者
liaoyijiaren 发表于 2013-6-18 16:50
IJK 可以给个相应的代码我吗?    我的邮箱是492319345@qq.com

可否上传一个你自己的低功耗例程?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

20

帖子

1

粉丝