本帖最后由 一个人破 于 2022-3-29 22:17 编辑
#申请原创# F030R8_让你简单学会低功耗编程(Part1浅谈篇)(以下内容是以APM32F030R8T6芯片为例)
写这篇帖子的初衷想想自己当初也是从菜鸟开始,在学习的过程中遇到各种各样的使用问题,然后反复上网查找资料,慢慢进步。为了守护那些懵懂无知的秀发,因此决定留下一些记录,也欢迎大家交流指正,愿世界再无脱发! 这篇主要是浅谈,并不打算讲具体的寄存器之类的,而是说说怎么进入真正的低功耗模式。因为寄存器之类的,都是可以自己看手册了解(真不是我懒啦,内容那么多)。如果能让你简单知道低功耗模式并能成功编程进入,那就ok了。内容并不深,后面可能还会出调试篇、应用篇。
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),然后看下有哪些外设时钟开关。 图3.时钟总线开关代码.png 可以看到这里有三条外设时钟总线开关: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)的效果图
下面同等条件下的是几种模式功耗比对 程序情况: 图5.测试代码.png
测试情况:(我这颗不代表所有的芯片,只是给大家看下它大概的配置效果) 图6.测试情况.png可以看到运行模式>睡眠模式>停止(on)>停止(LP)>待机模式 |
3、低功耗唤醒
进入低功耗之后,接着就是唤醒了。低功耗唤醒其实没什么好说的,也没遇到过什么坑,所以操作就不说了,可以自己看手册说明。不过这几种低功耗模式唤醒后,你知道程序分别是在哪里继续运行吗?我觉得这个还是有必要说说的。
1)睡眠模式和停止模式唤醒后其实都是从唤醒语句之后继续运行的。唤醒语句是啥?不知道你对低功耗模式库函数的参数“WFI”有没有印象。见下图: 图7.参数WFI.png 点进库函数,看看这里的参数:有WFI和WFE两种方式 图8.WFI和WFE.png |
WFI好比女巫的沉睡咒语,全称“WaitFor interrupt”等待中断,这条指令执行后MCU就进了低功耗模式,等到中断触发后MCU会被唤醒,此后程序继续在这个指令后面运行。 相同的,WFI还有个兄弟,叫WFE,“Wait ForEvent”等待事件。相同的用法,这条指令执行后MCU就进了低功耗模式,等到事件触发后MCU会被唤醒,此后程序继续在这个指令后面运行。 这里有个别人的链接可以帮你了解它们: https://wk.baidu.com/view/6d9b3101bfd126fff705cc1755270722192e5969
2)而比对待机模式的库函数,你是不是发现了什么。它没有给你唤醒方式的配置选择,这是写这个库的技术人员失误吗?不是,这是很巧妙的在引导我们,待机模式与其它模式的不同。因为待机模式唤醒后,是相当于复位的,它是从程序的最初重新跑一遍!
4、最后一点注意如果你是低功耗模式新人,然后使用我的附件程序,保证你绝不空军,能正常进入低功耗模式。但在重新下载程序时可能会遇到如下问题,并让你感到不知所措。你猜这是怎么了?自己看手册,联系低功耗的性质多想想。欲知详情如何,且听下回分解,《让你简单学会低功耗编程(Part2调试篇)》,帮助你了解更多低功耗的故事。 图11.error1.png file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image022.jpg 图12.error2.png |
参考资料编程软件:Keil uVision5 极海SDK:APM32F0xx_SDK_v1.5 极海用户手册:《APM32F030x6x8xC用户手册 V1.4.pdf》 极海数据手册:《APM32F030x6x8数据手册 V1.3.pdf》 *如有侵权,请联系我,我马上删除。
|