硬件上设计阶段完成,接下来就是我们的软件层次了。
一:端口引脚的配置
1 未使用的引脚:不用连接,配置为输出模式并驱动到任一状态(高电平或低电平);配置为输入模式并使用外部电阻(约10 k)拉至VDD 或VSS。
2 数字输入引脚:输入电压接近VDD或VSS时,引脚的功耗最低;输入电压接近(VDD+VSS)/2时,引脚功耗最高。
3 模拟输入引脚:模拟输入阻抗很高,引脚功耗很低。如输入电压接近(VDD+VSS)/2时,功耗低于数字输入,可考虑将数字输入引脚配置为模拟输入降低功耗。
4 数字输出引脚:只在引脚为外部电路供电时消耗电流,注意外部电路。
5 MCLR/IIC/开关/电阻分压器引脚:使用较大上拉电阻。如IIC上拉之后,减少电流消耗,代价是总线速度变低,折中设计。
二:关闭外围电路
对于外围传感器、EEPROM、LCD背光、收发器(RF/232)等功耗较高电路,IO引脚可以驱动的直接供电即可;不能驱动的可通过使能、禁止MOSFET驱动来供电。
三:工作电压
运行时,影响功耗的主要因素是时钟速度;休眠时,影响功耗的主要因素是晶体管中的泄漏电流。降低电压可有效降低切换系统时钟的电流和晶体管的泄漏电流。注意给定电压下的最高工作频率。
四:低功耗模式
1 空闲模式:CPU时钟断开,仅为外设提供时钟。当CPU需要最低程度的功能,在等待某个无法工作于休眠模式的外设事件时,适合采用空闲模式。
2 打盹模式:CPU时钟降低到某个较低的频率,外设以高速运行。当外设操作很关键,而CPU只需要低程度的功能,适合采用打盹模式。
3 使用NOP和空闲模式:将等待中断的循环替换为空闲模式。
while(!ADCInterruptFlag);
替换为:
while(!ADCInterruptFlag)
{
Idle(); // 在ADC 中断时唤醒
}
五:外设
不使用的外设,可以通过设置外设模块禁止位断开外设的所有电源。
六:从闪存执行与从RAM 执行
为MCU 的闪存供电和读取闪存是功耗最大的操作之一。从RAM读取所消耗的电能比从闪存读取所消耗的电能少。许多高端MCU(如PIC32)提供了从RAM执行代码的选项,以帮助降低动态功耗。
要从RAM 运行,必须将代码从闪存复制到RAM。此任务会消耗大量时间和电能。为了使该任务有执行价值,从RAM 运行的函数通常有大小限制,或应该是计算密集型函数。
七.MCU低功耗模式解析
不同制造商会对这些模式采取不同的命名方法。以下电源模式也得到其它制造商的大多数设备的支持:
1.工作模式:在此模式下,CPU和所有片上其它资源都正常工作运行。该模式是系统整体功耗的最主要组成部分。在此模式下,如果不使用的话,可将芯片上的各种外设分别断电。
2.休眠:这是控制器另一种常见的电源模式。该模式主要与CPU有关。当CPU进入休眠状态后,其时钟移除。CPU这时对总功耗的唯一影响就是静态功耗,因为这时已经没有时钟开关切换工作,也就不会有动态功耗。ADC和比较器等其它外设在此模式下可用
3. 深度休眠:此电源模式下即便是系统时钟也被禁用,所以在此模式下所有高频资源都不可用。不过,这些资源的当前状态不受影响,也就是说CPU寄存器、 SRAM等的当前状态不受影响。由于高频时钟被禁用,因此能节约开关消耗的功率。通常情况下,深度休眠模式提供低频时钟运行的选项,低频时钟可用来驱动定时器等低频资源。此外,该模式也允许开发人员使用I2C从设备等通信协议块,其无需器件自身生成时钟。由于进入此模式的主要方法就是禁用系统主时钟,因此这是可以实现的。然而,模块仍然可通电。该模式对功耗的影响主要在于片上所有时钟的静态功耗
4.冬眠:在此模式下,所有时钟都关闭,包括低速振荡器。片上所有资源,除了用于外部事件触发唤醒的资源以外全都断电。由于本模式下几乎所有组件都断电,因此该模式能减少静态和动态功耗组件,从而实现最低功耗。
5.停止:顾名思义,停止模式就是所有外设断电,即使是RAM和CPU寄存器的内容也不保持。在PSoC 4等类似器件中,这种模式下仅保持IO引脚的状态。从这种模式下唤醒会进入芯片重启动。
低功耗芯片的选型:主要有microchip、ti、st这三家。下面列举三家的典型的型 的参数。
八.软件设计需要注意点:
用“中断”代替“查询”
在没有要求低功耗的场合,程序使用中断方式还是查询方式并不重要。但在要求低功耗场合,这两种方式相差甚远。使用中断方式,CPU可以什么都不做,甚至可以进入等待模式或停止模式;而查询方式下,CPU必须不停地访问I/O寄存器,这会带来很多额外的功耗。
用“宏”代替“子程序”
子程序调用的入栈出栈操作,要对RAM进行两次操作,会带来更大的功耗。宏在编译时展开,CPU按顺序执行指令。使用宏,会增加程序的代码量,但对不在乎程序代码量大的应用,使用宏无疑会降低系统的功耗。
尽量减少CPU的运算量
减少CPU的运算工作量,可以有效地降低CPU的功耗。减少CPU运算的工作可以从很多方面入手:用查表的方法替代实时的计算;不可避免的实时计算,算到精度够了就结束,避免“过度”的计算;尽量使用短的数据类型,例如,尽量使用字符型的8位数据替代16位的整型数据,尽量使用分数运算而避免浮点数运算等。
让I/O模块间歇运行
在系统运行过程中,不用的I/O模块要关掉,间歇使用的I/O模块要及时关掉,以节省电能。同时,不用的I/O引脚要设置成输出或设置成输入,用上拉电阻拉高。
总之,在单片机系统设计过程中,需要深入理解单片机低功耗的特性,并在硬件和应用软件的设计过程中充分利用单片机的低功耗特性,从而设计出符合低功耗要求的产品。
八.
Mcu实现低功耗的本质而言是停止MCU工作,通过中断的方式重新唤醒MCU。这些中断可以包括外部IO中断,串口中断,定时器中断等。
如果结合嵌入式操作系统,可以在空任务或者空任务钩子函数中进入低功耗模式,在系统滴答时钟中断服务函数中重新回到正常工作模式。
空任务优先级最低且一直保持就绪状态,空任务可以用于统计CPU使用率,或者让mcu进入低功耗状态。也可以在空任务钩子函数插入低功耗代码。
(1)空任务或者钩子函数进入低功耗模式。
(2)系统滴答中断函数中退出低功耗模式。
(或者是空闲任务进入时开启低功耗,出去的时候退出低功耗)
Stm32F4系列低功耗模式
1.睡眠模式(内核停止)
2.停机模式(所有时钟关闭)
3.待机模式(1.8v电源关闭)
Sleep模式(内核停止,但是其他外设滴答时钟等还在运行)下任何中断均可唤醒stm32,而在stop(所有时钟停止)下,只能通过外部中断去唤醒。
Stop要比sleep模式要低,项目中选择使用
FreeRTOS:
Tickless 低功耗模式(替代了手动wfi指令(最终也是调用这个函数)进入睡眠模式的方法)
当任务挂起或者阻塞时,最低优先级的空闲模式得到执行,然后在低功耗模式中进行停机模式,设置低功耗唤醒时间进行唤醒。
1.降低系统主频 (满足需求下降低)
2.关闭可关闭的外设时钟
3.设置IO为高电平输出或者高组态输入(IO引脚做处理,防止上拉电流和灌电流增加功耗)
Stm32L476低功耗模式:
1.睡眠模式
Cpu停止工作,所有外设仍可以工作,使用中断或者事件进行CPU唤醒。
2.低功耗运行模式
使用最低电压提供内核电压,代码可以在SRAM和FLASH里面进行运行,cpu运行频率限制在2MHZ,外设使用独立16MHZ
3.低功耗睡眠模式
只有cpu时钟被停止,当中断或者事件唤醒CPU后进入低功耗运行模式
4.stop1和stop2模式
5.待机模式
6..关机模式
Tickless模式:
STM32 支持的睡眠模式,停机模式就可以放在空闲任务里面实现。但是,为了实现低功耗最优设计,我们还不能直接把睡眠或者停机模式直接放在空闲任务里。 进入空闲任务后,首先要计算可以执行低功耗的最大时间,也就是求出下一个要执行的高优先级任务还剩多少时间。 然后就是把低功耗的唤醒时间设置为这个求出的时间,到时间后系统会从低功耗模式被唤醒,继续执行多任务。这个就是所谓的 tickless 模式。
我们现在使用的系统节拍为1ms,会造成这种方式效果不明显吗
进入低功耗模式:
?当用户将宏定义 configUSE_TICKLESS_IDLE 配置为 1 且系统运行满足以下两个条件时,系统内核会自动的调用低功耗宏定义函数 portSUPPRESS_TICKS_AND_SLEEP():
- 当前空闲任务正在运行,所有其它的任务处在挂起状态或者阻塞状态。
- 根据用户配置 configEXPECTED_IDLE_TIME_BEFORE_SLEEP 的大小,只有当系统可运行于低功耗模式的时钟节拍数大于等于这个参数时,系统才可以进入到低功耗模式
函数 portSUPPRESS_TICKS_AND_SLEEP(); 是 FreeRTOS 实现 tickles 模式的关键,此函数被空闲任务调用,其定义是在 portmacro.h 文件中.
FreeRTOS 自带的低功耗模式是通过指令 WFI 让系统进入睡眠模式,如果想让系统进入停机模式/p>
https://blog.csdn.net/ZCShouCSDN/article/details/77879746
在freeRtosconfig.h里面添加了#define configUSE_TICKLESS_IDLE 1,通过定位也发现能够进入到空闲任务中
空闲任务:
xIdleTaskHandle = xTaskCreateStatic( prvIdleTask,
“IDLE”,
ulIdleTaskStackSize,
( void * ) NULL,
( tskIDLE_PRIORITYportPRIVILEGE_BIT ),
pxIdleTaskStackBuffer,
pxIdleTaskTCBBuffer );
空闲任务中:
计算用户所需空闲等待时间,没有获取到或者小于2,导致没有进入休眠,但是led任务阻塞时间应该大于2个时钟节拍啊,为啥这条不成立
使用stm32f103cb的板卡,有一个led灯任务。当使能Tickless模式后电流为6ma,不使能的时候为12ma,效果明显,但是L4的为什么不可以呢
Cubmx自动生成了一个任务,导致进入空闲任务后仍然无法获取到空闲时间,导致无法进入修眠,去除后可进入低功耗模式,之前电流为27ma,使用后为21ma。
L4系列和其他普通系列处理硬件本身耗电减少,提供的功耗方案也多,刚才验证的是睡眠模式,想达到更低的功耗可以在特定的场景下使用待机等其他模式
不同模式下freeRTos使用的函数时不一样的睡眠模式下最终调用的_wfi,其他模式具体看应用说明。
下面从降低主频和将不用的IO口设置状态两方面降低下功耗
降低主频是肯定可以降低功耗,但是要根据实际项目需求来设定。将主频的72MHZ降低到36MHz后由原来的21ma降低到17ma.
防止漏电流,将不用的管脚设置为下拉输入(固定模式即可),用的管脚加下拉后尽量不要输出高电平。之前的电流为21ma,将不用的管脚配置为下拉输入后,电流变为11ma,减少了10ma。
这篇文章整理比较着急,知识比较散,抽空在整理一下。
大体思路大家了解了就可以了。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!