打印

[技术贴] 【M0】 MG32F02A 学习笔记⑬ 低功耗模式

[复制链接]
149|2
跳转到指定楼层
楼主
 楼主 | 2018-10-19 13:21 | 只看该作者 |退出气泡模式 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 noctor 于 2018-10-19 13:24 编辑
    上回我们说到了MG32F02A的IWDT的使用。帖子详情:http://bbs.21ic.com/icview-2566570-1-1.html

      这回我们来说一下EXIC和低功耗模式的使用吧。
      首先,介绍一下, MG32F02A支持两种掉电模式:SLEEP、STOP两种,其区别在数据手册里面都有:

      此外,两种掉电模式的功耗肯定也是有区别的:

      那么,要怎么进入SLEEP和STOP这两种掉电模式?很简单,就是直接在你想进入低功耗模式时候执行这段代码:
  1. __WFI();//当然你也可以执行__WFE();

复制代码
     WFI与WFE的区别就是WFI是等待中断,WFE是等待事件,不过经过我多次测试,表示没啥区别,就直接WFI完事儿了。
      刚刚的代码是用来进入低功耗模式的,执行代码后,MCU就会进入SLEEP模式,那么,STOP模式又怎么进入呢?
      
      CPU寄存器的DEEP SLEEP位置1就可以了,然鹅,并没有找到相关的驱动函数能置位,但是我倒是找到了置位用的宏定义,于是,我去翻内存映射:

      就是你了,SCR寄存器!!
      于是,仿照着例程代码中的置位方法,就有了以下代码:
  1. SCB->SCR  = (SCB_SCR_SLEEPDEEP_Msk);    //把这句加在__WFI();前面就是进入STOP了
复制代码
     试试看吧,这样就可以进入STOP模式了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册
x
沙发
 楼主 | 2018-10-19 13:21 | 只看该作者
二楼附个代码

  1. #include "MG32x02z_DRV.H"
  2. #include "MG32x02z_ADC_DRV.h"
  3. #include "MG32x02z_PW_DRV.h"
  4. #include <stdio.h>

  5. typedef uint8_t u8;
  6. typedef uint16_t u16;
  7. typedef uint32_t u32;
  8. typedef uint64_t u64;

  9. void CSC_Init (void)
  10. {
  11.         CSC_PLL_TyprDef CSC_PLL_CFG;
  12.    
  13.        
  14.     UnProtectModuleReg(MEMprotect);             // Setting flash wait state
  15.     MEM_SetFlashWaitState(MEM_FWAIT_ONE);        // 50MHz> Sysclk >=25MHz
  16.     ProtectModuleReg(MEMprotect);

  17.   UnProtectModuleReg(CSCprotect);
  18.         CSC_CK_APB_Divider_Select(APB_DIV_1);        // Modify CK_APB divider        APB=CK_MAIN/1
  19.         CSC_CK_AHB_Divider_Select(AHB_DIV_1);        // Modify CK_AHB divider        AHB=APB/1

  20.        
  21.         /* CK_HS selection */
  22.         CSC_IHRCO_Select(IHRCO_12MHz);                        // IHRCO Sel 12MHz
  23.         CSC_IHRCO_Cmd(ENABLE);
  24.         while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
  25.         CSC_ClearFlag(CSC_IHRCOF);
  26.         CSC_CK_HS_Select(HS_CK_IHRCO);                        // CK_HS select IHRCO


  27.         /* PLL */
  28.         /**********************************************************/
  29.         CSC_PLL_CFG.InputDivider=PLLI_DIV_2;        // 12M/2=6M
  30.         CSC_PLL_CFG.Multiplication=PLLIx16;                // 6M*16=96M
  31.         CSC_PLL_CFG.OutputDivider=PLLO_DIV_2;        // PLLO=96M/2=48M
  32.         CSC_PLL_Config(&CSC_PLL_CFG);
  33.         CSC_PLL_Cmd(ENABLE);
  34.         while(CSC_GetSingleFlagStatus(CSC_PLLF) == DRV_Normal);
  35.         CSC_ClearFlag(CSC_PLLF);
  36.         /**********************************************************/

  37.        
  38.         /* CK_MAIN */
  39.         CSC_CK_MAIN_Select(MAIN_CK_HS);       


  40.         /* Configure ICKO function */
  41.                
  42.         /* Configure peripheral clock */
  43.         CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);

  44.   ProtectModuleReg(CSCprotect);
  45.    
  46. }

  47. int main()
  48. {
  49.         int i,j;
  50.         double x,y;
  51.         PIN_InitTypeDef PINX_InitStruct;
  52.         CSC_Init();
  53.         PINX_InitStruct.PINX_Mode                                 = PINX_Mode_PushPull_O;          // Pin select digital input mode
  54.         PINX_InitStruct.PINX_PUResistant                 = PINX_PUResistant_Enable;  // Enable pull up resistor
  55.         PINX_InitStruct.PINX_Speed                                   = PINX_Speed_Low;                         
  56.         PINX_InitStruct.PINX_OUTDrive                         = PINX_OUTDrive_Level0;         // Pin output driver full strength.
  57.         PINX_InitStruct.PINX_FilterDivider                   = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
  58.         PINX_InitStruct.PINX_Inverse                         = PINX_Inverse_Disable;         // Pin input data not inverse
  59.         PINX_InitStruct.PINX_Alternate_Function = 0;                                                 // Pin AFS = 0
  60.   GPIO_PinMode_Config(PINE(15),&PINX_InitStruct);                                          // D6 setup at PE15
  61.         i=0;
  62.         j=0;
  63.         while(1)
  64.         {
  65.                 i++;
  66.                 if(i>=500000){
  67.                         i=0;
  68.                         PE15=~PE15;
  69.                         j++;
  70.                         if(j>10)
  71.                         {
  72.                           PE15=1;                               
  73.                                 SCB->SCR  = (SCB_SCR_SLEEPDEEP_Msk);  //into stop
  74.                                 __WFI();             //This is the command of cmsis_arm.cc.  __WFI();is wait for interrupt while __WFE();is wait for event();
  75.                                 j=0;
  76.                         }         
  77.                 }
  78.         }
  79. }
复制代码
板凳
| 2018-10-19 16:40 | 只看该作者
感觉操作寄存器确实挺简单的,赞一个。
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册
本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

快速回复 返回顶部 返回列表