在之前的低功耗软件设计中也提到过一部分的stm32降功耗的方法,freeRtos系统帮我们写好的一个睡眠模式tickless,当我们的系统进入空闲任务后,就会自动睡眠,来达到降功耗的目的,打开方式也比较简单,在FreeRtosConfig中将宏定义 configUSE_TICKLESS_IDLE 配置为 1。就是这么简单,我当前用的片子是stm32L452,初步使用了这个方法,在72Mhz主频下,功耗在2ma,如果你想验证,直接通过ST提供给我们的CubeMX生成一下代码就可以了,在低功耗测试中,我们经常要更改主频或者管脚,使用cubMX生成代码是真的很方便。
在这个试验中我们会遇到一个问题,就是CubeMx生成的代码,打开宏定义之后不能进入睡眠。这个原因是因为CubeMX自动生成了一个任务,导致我们进入空闲任务后仍然无法获取到空闲时间,导致无法休眠, defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);屏蔽掉这个任务就可以了。
上面我们说的都是tickless这个模式,但是作为低功耗产品来说,这个功耗还是很大怎么办,那么就要我们就要将MCU切到其他模式下,进一步的降低功耗。
说道这里就要说一下stm32的低功耗模式了,之前我们的stm32F系列四种模式,L系列为5种,L系列近几年发展很快,模式多,电源管理及低功耗外设,还有漏电流比F系列小很多。
每种模式肯定功耗不一样啊,但是要根据产品的需求来选择合适的模式。
上面这两个图比较重要,这样我们就可以知道哪种功耗最低,怎么进入模式,怎么退出模式,有没有唤醒延时,唤醒后,RAM数据是不是还存在等等,都是重要的评估标准。
有的模式任意中断都可以唤醒,有的则必须外部中断或者特定中断唤醒,有的无唤醒延时等。
说道这里我们肯定要了解我们的MCU的时钟情况,CubeMx的作用就来了,以stm32L452RE为例:
下面主要说两种模式,低功耗运行模式和低功耗stop2模式
低功耗运行模式首先在几种模式中功耗算低的,并且内核和外设都可以保持运行状态
Stop模式,内核停止,Vcore范围内的时钟停止,PLL,MSI,HSI,HSE都被禁止,SRAM和寄存器的值保留,功耗够低。
低功耗运行模式在freeRtos中的应用也很简单分为几部
- freeRtosConfig.h中添加三个宏定义
#define configUSE_TICKLESS_IDLE 1 (使能低功耗模式)
#define configPRE_SLEEP_PROCESSING(x) OS_PreSleepProcessing(x) //睡眠入口
#define configPOST_SLEEP_PROCESSING(x) OS_PostSleepProcessing(x)//唤醒后操作
- 添加用户函数
低功耗运行模式就完了,比之前的tickless模式功耗要低一点点。
停机模式的使用耗费了很多的经历,过程中出现了很多的问题,比如说默认使用的HSE时钟,滴答定时器在stop模式唤醒后变慢。
最开始的时候我就是按照上面的步骤在入口函数中添加睡眠指令HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
在唤醒出口函数中添加对时钟重新的配置。
Stop模式后,PLL时钟被停掉了,我们开始的时候用的PLL时钟,stop模式唤醒后,默认的使用内部MSI时钟。
通过这个思路我开始用的HSE时钟,唤醒后我重新SystemClock_Config(),一下应该就可以了,但是还是慢, 上也都说需要重新配下时钟,但是没有人说怎么配置。。无语啊。
那么我换条思路,不唤醒后默认使用MSI时钟吗那么我开始的时候就配置为MSI时钟,使用48Mhz,这样配置后,确实不变慢了,也足以说明,确实唤醒后使用的MSI时钟,但是这个时候出现了一个问题,我板卡重启后,板卡无法运行,只有debug下能运行,感觉像是只能RAM运行,falsh中找不到时钟配置似的,还有个问题就是停机模式下确实功耗降低了,但是在1ma左右,没有达到理想值ua级别。
这下回到的原点
官方的例程使用的是无系统的,我想使用系统,同样也是上面的操作,增加两个用户函数,在里面实现睡眠动作和唤醒后的操作。
这样我们的睡眠和唤醒就正常了,我们使用 prvGetExpectedIdleTime(),动态获取空闲时间,避免我们在睡眠过程中,错过任务操作,睡眠和唤醒时间由实时系统说了算。
St的历程跑的很好,我们在移植的过程中仿佛并不是那么顺利,会遇到第一个问题。
if( HAL_RTC_Init(&RTCHandle) != HAL_OK)
{
/* Initialization Error */
}
移植到我们的板子后,RTC时钟初始化不通过,st历程好好的,其实st也做操作了
增加这两个函数后,我们就发现可以运行通过。但是又出现了一个问题
我调用了delay_ms的一个延时,却出现了问题,整个程序进入硬件中断。
在freeRtosConfig.h中添加这个宏定义即可解决。
#define INCLUDE_xTaskGetSchedulerState 1
其他的函数可以看一下我提供的源代码,这里不着重的说了。
在我们的实际应用中一定要尽量的使系统多处在空闲任务中,这样才能长时间进入模式
为了满足我们的项目需求,我们还可以通过标志位来切换到不同的模式中,例如:
上搜索下载的文档及官方测试代码还有修改的代码,将全部开放下载,可以在下面链接中下载到。绝对超值。
上面的方法目前还没有长期测试,只为大家提供一点思路。如有问题可留言讨论。
注:
当你要包含新的hal库文件时,除了添加相应的.c文件,引用.h文件外,一般还要在stm32l4xx_hal_conf.h中打开相应的
宏定义。
另外使用低功耗的模式的时候,要注意FreeRTOSConfig.h文件中的宏定义,有的时候打开了不必要的宏定义,会使低功耗模式下,任务出现无法调度的情况。(低功耗模式正常,但是任务无法调度),同时系统时钟中断,RTC_WKUP_IRQHandler等中断的实现也要小心修改
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!