极海半导体APM32F030R8T6如何低功耗编程
极海半导体推出的APM32F030R8T6如何低功耗编程
1、低功耗概述
低功耗模式,顾名思义就是可以让MCU在更低的功耗情况下运行。相关资料可以看用户手册第六章,电源管理单元(PMU)的内容,详见《APM32F030x6x8xC 用户手册》。
 
 
其中主要是3种模式:睡眠模式、停止模式、待机模式。当然,其实也可以细分为4种模式,因为STOP模式有两种分支。
Ø  睡眠模式 (Sleepmode) (CPU 时钟关闭 , 所有外设包括内核外设如 NVIC, SysTick, 等仍在运行 )
Ø  停止模式 (Stopmode) ( 所有时钟都停止 )
Ø  待机模式 (Standbymode) (1.8V 供电域断电 )
同等条件下的功耗排序:运行模式 > 睡眠模式 > 停止模式 > 待机模式
那该如何进行编程,让MCU运行在低功耗模式下呢?

2、常用的三步法
1)将无用的IO配置为模拟输入状态
查找数据手册,我们可以看到APM32F030R8T6的GPIO有A、B、C、D、F口
    
file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg
代码如下:
  
void GPIO_ALL_init(void)
{
         GPIO_Config_T  gpioConfig;

     /** Enable the GPIO Clock */
         //F030R8没有GPIOE
  
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA|RCM_AHB_PERIPH_GPIOB|RCM_AHB_PERIPH_GPIOC|RCM_AHB_PERIPH_GPIOD|RCM_AHB_PERIPH_GPIOF);
  
  
     /** Configure the GPIO_LED pin */
  
     gpioConfig.pin = GPIO_PIN_ALL;
  
     gpioConfig.mode = GPIO_MODE_AN;
  
     gpioConfig.speed = GPIO_SPEED_50MHz;
  
     gpioConfig.pupd = GPIO_PUPD_NO;
  
  
     GPIO_Config(GPIOA, &gpioConfig);
  
     GPIO_Config(GPIOB, &gpioConfig);
  
     GPIO_Config(GPIOC, &gpioConfig);
  
     GPIO_Config(GPIOD, &gpioConfig);
  
//      GPIO_Config(GPIOE,  &gpioConfig);
  
     GPIO_Config(GPIOF, &gpioConfig);
  
RCM_DisableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA|RCM_AHB_PERIPH_GPIOB|RCM_AHB_PERIPH_GPIOC|RCM_AHB_PERIPH_GPIOD|RCM_AHB_PERIPH_GPIOF);
  
}
  

2)关闭外设时钟
外设时钟可以参考用户手册的时钟树。不过一般都是直接点开 关于时钟的库函数(rcm.h),然后看下有哪些外设时钟开关。
   
可以看到这里有三条外设时钟总线开关:AHB、APB1、APB2
  
代码如下:
  
//关闭外设时钟
  
RCM->AHBCLKEN = 0;
  
RCM->APBCLKEN1 = 0;
  
RCM->APBCLKEN2 = 0;
  

3)进入低功耗模式
进入低功耗模式的配置其实很简单,也是三步:打开电源管理的时钟、清除唤醒标志、进入想要的低功耗模式。
代码如下:
  
/* 低功耗程序 */
  
//系统进入睡眠模式
  
void Sys_Enter_Sleep(void)
  
{
  
         RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);//使能PMU时钟
  
         PMU_ClearStatusFlag(PMU_FLAG_WUPF);//清除唤醒标志
  
         PMU_EnterSleepMode(PMU_SLEEPENTRY_WFI);
  
}
  
  
//系统进入停止模式——PMU_REGULATOR_ON
  
void Sys_Enter_Stop_on_Mode(void)
  
{
  
         RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);//使能PMU时钟
  
         PMU_ClearStatusFlag(PMU_FLAG_WUPF);//清除唤醒标志
  
         PMU_EnterSTOPMode(PMU_REGULATOR_ON,PMU_STOPENTRY_WFI);
  
}
  
  
//系统进入停止模式——PMU_REGULATOR_LowPower
  
void Sys_Enter_Stop_Lowpower_Mode(void)
  
{
  
         RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);//使能PMU时钟
  
         PMU_ClearStatusFlag(PMU_FLAG_WUPF);//清除唤醒标志
  
         PMU_EnterSTOPMode(PMU_REGULATOR_LowPower,PMU_STOPENTRY_WFI);
  
}
  
  
//系统进入待机模式
  
void Sys_Enter_Standby(void)
  
{
  
         RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);//使能PMU时钟
  
         PMU_ClearStatusFlag(PMU_FLAG_STDBYF);//清除唤醒标志
  
         PMU_EnterSTANDBYMode();
  
}
  

下图是进入停止模式(Sys_Enter_Stop_Lowpower_Mode)的效果图
  

下面同等条件下的是几种模式功耗比对
  
程序情况:
  
  
测试情况:(这颗不代表所有的芯片,只是看下它大概的配置效果)
  
可以看到运行模式>睡眠模式>停止(on)>停止(LP)>待机模式
  

3、低功耗唤醒
进入低功耗之后,接着就是唤醒了。低功耗唤醒其实没什么好说的,可以自己看手册说明。不过这几种低功耗模式唤醒后,你知道程序分别是在哪里继续运行吗?

1)睡眠模式和停止模式唤醒后其实都是从唤醒语句之后继续运行的。唤醒语句是啥?不知道你对低功耗模式库函数的参数“WFI”有没有印象。见下图:
  
点进库函数,看看这里的参数:有WFI和WFE两种方式
  
WFI好比女巫的沉睡咒语,全称“WaitFor interrupt”等待中断,这条指令执行后MCU就进了低功耗模式,等到中断触发后MCU会被唤醒,此后程序继续在这个指令后面运行。
相同的,WFI还有个兄弟,叫WFE,“Wait ForEvent”等待事件。相同的用法,这条指令执行后MCU就进了低功耗模式,等到事件触发后MCU会被唤醒,此后程序继续在这个指令后面运行。
  

2)而比对待机模式的库函数,你是不是发现了什么。它没有给你唤醒方式的配置选择,这是写这个库的技术人员失误吗?不是,这是很巧妙的在引导我们,待机模式与其它模式的不同。因为待机模式唤醒后,是相当于复位的,它是从程序的最初重新跑一遍!