3.低功耗设计-软件设计阶段

 

硬件上设计阶段完成,接下来就是我们的软件层次了。

 

一:端口引脚的配置

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 让系统进入睡眠模式,如果想让系统进入停机模式???

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。

 

这篇文章整理比较着急,知识比较散,抽空在整理一下。

大体思路大家了解了就可以了。

 

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值