文章目录
- 前言
- 1、低功耗的概念
-
- 1.1、一种AD采样功耗优化方案
- 2、硬件低功耗设计概述
- 3、软件低功耗设计概述
- 4、软件低功耗设计详述
-
- 4.1、应用模块化、功能任务化、任务周期化
- 4.2、功耗自理化、休眠一票否决化
- 5、低功耗软件设计具体步骤
-
- 5.1、低功耗设计第一步:自底向上,顺藤摸瓜
- 5.2、”先搞清楚我们是怎么睡的”
- 5.3、”再搞清楚我们是怎么醒的”
- 6、试探功耗底限的系统配置方式
-
- 6.1、对AVR来说,不用的引脚怎么办/li>
- 6.2、对AVR来说,需要使用的引脚怎么办/li>
- 6.3、说说PRR寄存器
- 6.4、说说工作频率
- 7、 低功耗设计第二步:让我们来下棋,很大很大的一盘棋
-
- 7.1、工欲善其事,必先利其器
前言
??不知从什么时候开始,随便做个什么电子产品,至少是电池供电的,都要求低功耗特性了。好在市面上随便什么芯片都敢在自己的数据手册的第一页赫然写着低功耗。究竟怎样算低功耗于5mA于1ms于100uA开了应用场合,似乎数值也失去了单纯的意义,总之越小越好。但感觉上,能用水果点亮的应用应该就是低功耗了吧。
??认真说来,有点怀念当年随便一个应用500mA,芯片微微发烫,用手一摸只要还能放得住就大手一挥“没问题”的时代了。最近总是和uA打交道,超过100uA,周围的人脸色就不好看了,好容易达到了传说中的20uA以内,也会觉得沾沾自喜,哎……uA啊……情何以堪啊,伤不起啊……
??久病成医,渐渐的也就有了一些心得,似乎低功耗开发的过程也可以一板一眼,按部就班,似乎不单纯是一些零散的“看情况而定”“只可意会”的东西了。于是忍不住,将这些似是而非的步骤记录下来,以箪初来者。
??Hold your 板砖。Thanks。
1、低功耗的概念
??“肚子饿的时候,睡着了也就不觉得饿了……于是乎,难得的双休日宅在家中补觉,往往也就
??一天只吃一餐饭了”——技术宅人_大体如此。
??应该没有人能在梦游的时候干活吧以,平常工作的时候,饭还是要吃的。休眠和干活应该是一对矛盾体。于是乎,芯片数据手册上那些“小的出奇的休眠功耗,似乎大部分时候只是用来摆设的;而工作功耗才是实实在在的东西。有时候,为了体现所谓的低功耗,还要在应用中设计一种所谓的低功耗模式——当系统确认没有事情可做一段时间以后就干脆回家睡觉了——这大体就是现在市面上常见的低功耗应用的某种程度上的现状吧。于是乎,降低工作频率这种“马儿跑,马儿不吃草”的逻辑,就成为降低正常工作模式下系统功耗的常规选择。苦啊……多少人在工作频率和功耗间纠结……又有多少功能实现的本身对对频率拥有最低要求……苦啊——我说的是写代码的程序员。
1.1、一种AD采样功耗优化方案
??说起来,降低功耗似乎是一个软件和硬件协同工作才能解决的问题。比如AD采样时候的分压电阻,如果直接接了地,那么就会一直消耗电流,如果通过一个IO口来控制其接地的方式,只在需要采样的时候接地,采样完成以后就悬浮或者拉高,就可以将这部分开销降低的最小。

??这种系统设计模式看似有点本末倒置——还没有搞清楚需求就已经把芯片定了——实际上,这种方式非常符合我们通常的开发模式:先有了一个初步的概念或者备选芯片方案,这些方案可能来自一个已有的方案,一个已有方案的兼容方案,一个老板或者老员工/经验者提出的方案——总之有了一个基础或者说原形,我们开始调查和研究具体低功耗的可行性,并形成了一个研究 告,这一 告将直接指导下一步的行为:由于需求非常明确,我们可以决定是否更换芯片或者直接进入下一步的开发。上面三个步骤实际上形成了一个LOOP,这一loop其实来自于“快速原型法”这一古老的“敏捷”开发模式自然,规范,高效。
??完成了以上两个步骤,可以说这一阶段就结束了,至此我们对系统的关键性能数据已经成竹在胸:系统最低能实现多大的功耗;外设某些敏感的参数设置将如何影响功耗——当我们需要在外设性能和功耗之间做妥协和权衡的时候这些信息就将发挥巨大的作用;我们甚至对系统外来如何工作,或者说系统最基本的问题:“时间问题,整个复杂的多米诺骨牌是从哪里被什么推倒第一张牌的”大致有了了解。我们甚至知道,如果不出意外系统将会达到怎样的功耗。
6、试探功耗底限的系统配置方式
6.1、对AVR来说,不用的引脚怎么办/h2>
>> 如果这个引脚属于ADC采样引脚
??i)通过DIDRn寄存器关闭对应引脚的数字输入,这个时候PINX对应位将永远读取到0
??ii)通过DDRx和PORTx寄存器将对应的引脚设置为输入,“关闭”上拉电阻
>> 如果这个引脚是普通的GPIO
官方推荐的方式是给这个引脚一个确定的电平,比如:
??i) 通过DDRx和PORTx寄存器将对应的引脚设置为输入状态,并“开启”上拉电阻
??ii)通过DDRx和PORTx寄存器将对应的引脚设置为输出状态,并输出低电平,PCB设计上,将该引脚接地。
>> 如果这个引脚是RESET引脚当电路要求保证稳定的情况下尽可能简化,同时,VCC电压在上电时刻电压升高速度不会很缓慢,则接外部上拉电阻到VCC,这样虽然对功耗影响不大,但是可以适当提高一点抗干扰性。
>> 如果这个引脚是扩展的ADC引脚基本可以不管,或者接地。
6.2、对AVR来说,需要使用的引脚怎么办/h2>
>>如果这个引脚是开漏输出/线与输入的引脚,比如TWI,同时需要与外部设备连接,而这一连接是允许拔插的
?? i) 如果逻辑上允许,接下拉电阻。
??ii)如果是外中断引脚或者因脚电平变化中断引脚,避免悬浮,相比上拉来说,尽可能选择下拉。这样设置的目的是避免不确定电平经常将系统唤醒。选择下拉的原因是将高电平的选择权力交给外部设备,同时更倾向于盗电(_)。
>> 对于ADC引脚
??i) 如果永远不会用于数字信 的输入用途,请参考空闲引脚的处理方式。
??ii)如果需要用作数字信 的输入用途,请在通过PINx读取电平前,通过DIDRn寄存器打开对应引脚的数字输入,并插入两个NOP后读取电平,完成读取后,立即关闭数字输入功能。
>> 对于控制信 引脚
??i) 直接驱动LED总是悲剧的开始,别忘记加入限流电阻,尽可能使用高亮LED。
??ii)如果非要输出电平的控制信 ,请认真考量有没有漏出电流的可能,如果有,请尽可能在不需要输出控制信 的情况下,将IO口处理为无电流漏出的状态(或最小小电流漏出的状态,关于出还是入的语言文字问题,你懂的),具体状态图应该由硬件设计人员给建议。总原则就是按需分配。
6.3、说说PRR寄存器
>>如果某个外设的供电通过PRR寄存器的设置被掐断了
??i) 除非特殊说明,否则这个外设的所有寄存器都是无法正确读写的
??ii)如果在外设供电关闭前,外设的中断标志没有被清零;或者说正在执行这个中断处理程序的时候该外设被断电了,则中断标志不会被清除。表现症状就是中断持续被触发。其实想想很简单,参考i)就知道了。
??iii) 很多时候,关闭定时器这样的外设并不能减少多少功耗,基本上都是小于5uA的。经验上关闭那些和模拟特性相关度较大,或者拥有独立相关的时钟源的模块,通常会减少不小的功耗。
??iv) 谨慎使用该功能,除非你认真阅读了数据手册。这也是很多人所谓休眠醒不过来或者工作不正常的主要原因之一。
6.4、说说工作频率
>>在正常的工作模式下,频率越高功耗越高。
??i) 推论1:对于同样一个工作,频率越高,完成该工作的时间越短
??ii)推论2:根据Equation A,对于同样一个工作,Active的时间越短,则Sleep的时间越长。
>>假设频率翻倍,功耗增加4倍,则:
??i) 推论3:通常Sleep功耗至少为某一个频率功耗的4分之一甚至更大。当频率翻倍的时候,工作时间缩短一半,假设功率翻倍时功耗为4倍,则Active部分的实际功率翻倍 ( 50 % ? 4 ) (50% * 4) (50%?4);同时,节省出来的时间成为Sleep功耗,此时,系统的功耗变化为:
??假设频率翻倍前的Active功耗认作 C,工作时间为T,则:翻倍前Active部分的功耗为 C ? T C * T C?T频率翻倍后,Active的功耗为 4C,工作时间为 T/2;同时,假设Sleep的功耗为 C/4,则翻倍后的实际功耗为4C * (T/2) + (C/4) * (T/2) = 4.25C * T / 2 = 2.125 (C * T)可见频率翻倍后实际功率为增加前的2.125倍。显然从功耗的角度来说并不划算。
??但请注意,Sleep功耗通常远远小于这里的1/4,以ATmega88为例,1MHz VCC = 2V的情况下最大功耗是550uA,而Sleep模式(Power-down VCC=3V)最大功耗是15uA,差不多36倍。在这种情况下,显然频率翻倍,功耗接近2倍。
??有意思的是,如果对以上公式进行迭代,你会发现,频率越翻倍,Sleep功耗和翻倍前的Active功耗差距越大。也就是说基本上每次翻倍,功耗基本上可以认为是翻倍的。同时频率增高带来的好处却是运算速度每次都翻倍的。从这个角度来说,是否频率越高越好呢速度快,功耗增加小)。再联系到那些与外部引脚操作直接相关的功耗,频率越高,外部引脚操作中可控的功耗部分就小(请联系前面AD的例子),那么从这个角度来说,似乎功耗还会减小一些。
??再次强调,以上结论建立在工作完成后立即休眠的工作模式下,同时Sleep模式的功耗必须远远小于Active功耗(通常8~10倍),使用外部时钟源,以及晶体振荡器所需的额外功耗,及从休眠中唤醒时时钟稳定期间所需功耗都未作考虑。
>>实际上,MCU的功耗分为两个部分,一个与频率有关,一个与工作电压有关,即
E = E ( V ) + E ( f ) E = E(V) + E(f) E=E(V)+E(f)
??当频率翻倍时,影响的只是E(f),而这部分功耗并不会最终导致4倍的功耗,其值往往在2倍甚至更低。在这种情况下,Sleep+Active的工作模式会带来更低的功耗。证明略。
>> 通常,我们测量功耗的方式就是测量电流
??i) 推论4:在非积分式功耗测定方式中,如果工作频率越高,则Sleep时间越长,在电流测量的时候,Active电流越接近于“毛刺”,这就导致了频率越高,功耗越低的假象。因为大部分的电流采样点都落在了Sleep上。
??ii)推论5:采用积分式功耗测定方法才能正确的测定实际功耗。当然,如果你想骗骗普通客户,高精度电流表的电流结果(甚至是平均电流)都将反馈给你一个“非常理想的结果”。
7、 低功耗设计第二步:让我们来下棋,很大很大的一盘棋
??通过上一节的讨论,假设在您的设计中对应的步骤已经完成,则我们至少获得了以下信息和结果:
- 一个极限功耗
- 一个可行的系统工作模式(满足应用需求同时兼顾低功耗的系统节拍)
- 当使用2中提及的系统工作模式时,通过公式计算获得的理论系统功耗(系统正常工作下的功耗)
??显然,万事俱备,只欠东风,就只剩下具体实现了。别着急,我们先来搞清楚几个定义。
A.普通工作模式(Normal Mode / Active Mode)
??这里的普通工作模式是指能够实现正常系统功能的模式,在这种模式下,MCU并非一直处于工作状态,而是根据前面一章提到的功耗公式,结合了Active和Sleep两种MCU状态的模式。简而言之,一个保证了应用基本功能的同时能休眠就休眠的工作模式。
B.低功耗模式(Idle Mode / Sleep Mode)
??这里所说的低功耗模式是指根据用户的应用需求,在用户指定或者系统自动侦测满足某些特定条件的情况下,尽可能关闭不需要的功能,仅保留某些应用必须的任务以降低功耗为目的的模式。(例如一段时间没有用户操作就关闭LCD和LED背光)
??总结来说,这里的普通工作模式和低功耗模式都不直接对应MCU提供的Active和Sleep模式,而是两个根据用户功能需求定义的具有不同功能配置的功耗模式。他们可能都牵涉到MCU的Active和Sleep状态。明确了这两个定义,我们后续讨论中牵涉到的很多说法才不会混淆。
7.1、工欲善其事,必先利其器
??在实践低功耗系统设计前,我们必须要有一个有效的手段来检测或者说观察系统当前的工作模式,通俗的说就是要能够随时知道系统什么时候工作,什么时候休眠,并且最好能够准确的知晓工作和休眠的时间比例。对于缺乏高精度电流表的场合来说,这种观测手段就更为重要了。
??简而言之,我们需要一种实时追踪(trace)系统功耗模式的调试(Debug)手段。既然是实时追踪,意味着断点、单步这种常见的手段是不行的,系统必须保证处于正常的非间断工作状态下。同时,作为Debug,必须能够准确显示休眠和工作的状态,并能够将这些信息保存下来,大家可以在脑海里想像有这么一个类似地震记录仪的设备,一直不停的在纸带上记录着功耗变化的信息。说的这么复杂,其实做起来很简单。Debug阶段,我们关系的是系统如何休眠的,其实际功耗可能由于Debug手段的存在而并不准确,但这一信息已经足够了,因为在随后的检测中,我们可以生成一个release版本(移除了debug相关的代码)直接通过电流表检验系统功耗。Code 2.1就是一个很好的例子。代码在休眠前在某一个信 引脚上输出高电平,在退出休眠模式后输出低电平。此时,借助示波器或者逻辑分析仪的帮助,我们就可以记录并检测系统的功耗模式,甚至根据数据手册提供的Active电流和Sleep电流计算出一个非常接近实际结果的理论_功耗。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!