你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【原创】【MCU实战经验】分享一个低功耗项目小小心得

[复制链接]
xiao zhang-2012 发布时间:2014-4-30 14:54
只看帖不发帖是不好的,我也来发发帖子吧,写的不好谅解啊。
5 Y7 j3 ^- e# q前两个月在公司做了一个低功耗项目,现在功耗最低10uA不到,平均功耗40uA左右,算是达标了。因为是公司产品,就不方便贴代码、原理图了,该产品是一个小模块,可以方便的嵌入到各种系统里面。跟原子哥他们卖的NRF2401类似,是一个读卡器。3 d2 X3 m# w0 g* F0 b7 z  d- V  Y
做这个项目中间也请了技术支持,因为外围电路芯片的功耗一直降不下来,经过与对方的反复交流,对方提供了低功耗的测试结果、硬件方案、软件方案,经过修改测试,最终成为我们的产品,功耗比较满意。
- G. h( }  t" r& u% Y. R& K% A硬件方案选择的是STM32,外加某公司的读卡芯片。前期完成了读卡等功能的开发,最后一项开发内容是最艰巨也是最困难的---低功耗。在开发过程中,从硬件设计上不断裁剪元器件,软件上不断精简代码,功耗最低都保持在3-4mA。2 v7 A- W: F9 n6 X; F
 
1 A% l4 ^5 q6 u# W  A电路设计上,只用到了一个LED、串口1、一个模拟SPI、一个中断线、一个读卡芯片RESET线,硬件上就只剩下这么点东西了,这个时候我采用的是待机模式,使用的是读卡芯片的中断接PA0唤醒STM32,在此之前要先使得读卡芯片进入低功耗、然后STM32进入低功耗,这一步完成了,貌似没什么问题,功耗确实从几十mA骤降到3mA左右,开始还挺满意的,但是测试厂商提供的样板,功耗却只有几十uA,有点郁闷了。为什么会这样?反复查看硬件、程序,都找不出原因,而且这个时候的工作效果很烂,根本就不能唤醒,所以我就怀疑是读卡芯片一端低功耗有问题,因为我将PA0脚直接短接VCC,这样就可以产生一个边沿触发STM32唤醒了,但是用读卡芯片无法唤醒,所以我怀疑是读卡芯片的RESET脚电平不对,经检查,确实是因为RESET脚加了上拉电阻,读卡芯片是高电平复位,在STM32进入待机后,管脚全都浮空了,导致RESET被拉高,一直在复位;我去掉上拉电阻,觉得很有希望解决问题了,但是测试结果是:有时候能唤醒,有时候不能,我仔细一想难道是因为STM32待机后管脚电平不确定,导致读卡芯片RESET脚电平不定,而工作不正常,看样子只有换用其他方案了。后面确实验证了我的想法,使用STOP模式后,唤醒问题引刃而解。' Y/ D+ q6 Z' F6 k: p  K
就在关键时刻,芯片原厂火种送炭,送来急需的技术支持资料,一个包含低功耗源代码,赶紧拿过来测试,先研读下代码,使用的是STOP模式,而不是待机模式,使用的是任意外部中断唤醒,功耗低制40uA,这个时候就相当激动啊,赶快下载测试啊,结果功耗确实降了,但还是有1mA,更人家一比多了几十倍啊。。。
* \8 K* T& L- D$ a5 M% H7 I我第一反应是硬件不对,经过测试修改,首先找到第一个原因,读卡芯片RESET管脚上拉电阻又给焊上去了...,拆掉后功耗骤降到几百uA,还是不行。。 测试过程中,为了去掉LDO的干扰,整板采用3.3V供电,但是后面经过测试,LDO的功耗其实也只有5uA不到,这LDO功耗值得赞一个;虽然结果还是没达到预期,但是看到了希望,胜利就在眼前啊。/ u8 g, a/ X& H1 l
为此我反复看了技术支持提供的程序,发现他们的STM32的所有管脚都的设置都有所考究:(因为公司保密原则,代码中删除掉了关于该读卡芯片的前缀信息等)
' I6 n; G, O$ h/ O, V" ?GPIO_InitTypeDef GPIO_InitStructure; 8 d; `8 ?, W) }

; S& y) I6 g: g% X# _( y/* GPIOA Periph clock enable */+ P) R: J0 O- d, ~2 Q3 b) L/ z
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
& f% ?8 R1 n6 b, [- ?4 h* r/* GPIOB Periph clock enable */
  w! O. g/ f. w6 N' e5 URCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
* m# [3 E, F& ]/* GPIOC Periph clock enable */  Q# w! y+ e" B. Q- E  d; R
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);   v: A! ]: a. F$ e% B9 X

1 I5 L2 X% O% V& s/ R% N1 uRCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 4 y* d9 x. ^1 ]% ~* u

( g( o, u) z# d5 ~; c, lRCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
0 q0 ~7 ]: `) l3 D/ Y//####################################################
& |3 N/ ?9 G& V: G* i' U//USART1 Port Set
$ n# c% V- i% j2 G- ?//TXD
0 H# `' H9 c7 F- r$ N2 oGPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
1 G4 B5 z9 }1 _GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;& \: L0 O4 a/ y# @# `" v' q. O
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;3 M) y/ S/ A3 C& k5 M; E
GPIO_Init(GPIOA, &GPIO_InitStructure);
( o" ~: N6 R' a& e3 Z( p//RXD
$ M2 ?& ^6 T. L% u- U5 C8 DGPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;* [% U( E' t5 w* E
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
) z+ r: x) A- @% ^GPIO_Init(GPIOA, &GPIO_InitStructure);
! k2 `+ n- h8 |( S: B
/ Y% o5 x% g3 |3 F9 [) h% t//RST output pushpull mode
- X' F6 w: r0 A' N7 nGPIO_InitStructure.GPIO_Pin = TRST;, E6 U; [8 y4 N
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
) S7 p2 F, ^4 {7 \0 l+ jGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
' k6 A4 k& S% o+ }GPIO_Init(PORT1, &GPIO_InitStructure);
) [  E2 b" F# p5 G# T, i! B//IRQ input pull-up mode
% U3 Z) C* T, ~+ h# d. \GPIO_InitStructure.GPIO_Pin = TIRQ;" g/ `& G' m1 u
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
0 I+ x8 t6 n& `% w" m& L( T2 p& vGPIO_Init(PORT1, &GPIO_InitStructure);5 s+ D6 z  p# U* N
//MISO input pull-up mode
( w, V6 Z# ?$ qGPIO_InitStructure.GPIO_Pin = MISO;
& g/ M  s% e; Q+ GGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
# l! D+ R3 u/ Z  ]$ }GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
6 H% N7 \! R6 G3 m+ _GPIO_Init(PORT2, &GPIO_InitStructure);
# Q  t3 g% Q) z& m//NSS,SCK,MOSI output pushpull mode! B+ {+ k( Q5 X( q" F3 o- N2 t
GPIO_InitStructure.GPIO_Pin = (NSS|SCK|MOSI);
5 u; V% f: j& nGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;' `- W* P2 {! c3 y
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;7 ~4 p) O: T" |
GPIO_Init(PORT2, &GPIO_InitStructure);
2 e$ K# H: \$ t' B  k( J3 N& @7 x7 o2 q//############################################################################
- `; e0 y  ?7 Z) {) e$ z6 e//TEST Port set
- c# }. p! V1 \% m4 M) A//TESTO input pushpull mode
% X( j) D. b0 |3 v3 M4 g) L/ XGPIO_InitStructure.GPIO_Pin = TESTO;
+ T7 \6 D7 ?$ c- q0 qGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
( x; G! ^' _/ ]" f5 q- z+ \5 N+ y. H0 uGPIO_Init(TEST_PORT, &GPIO_InitStructure);# c, G& R: ~, E* N: W% H
//############################################################################
$ z7 b4 a8 v$ k$ d# h//TEST Port set
( R# ~0 d+ X- P  D4 u//TESTI output pushpull mode* y' \# E8 w2 g0 o* l# Z
GPIO_InitStructure.GPIO_Pin = TESTI;# i6 u# y6 P, A2 I
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
* M6 n& j- g) l% DGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  H1 O1 Y+ H6 a, b) cGPIO_Init(TEST_PORT, &GPIO_InitStructure);" P4 c9 Z8 t/ g! t. v
//############################################################################/ O+ y9 J  Z+ h' N7 m
//LED Port Set5 Z+ j' h' _. q; C- O
//LED output pushpull mode" k0 i; F4 ]8 \' C
GPIO_InitStructure.GPIO_Pin = LED;
* V$ o4 a$ A( hGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;3 N. O7 G+ k. ~: z/ _
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;1 d& w6 J# H) }% n% P7 u
GPIO_Init(LED_PORT, &GPIO_InitStructure);
; y  c, F% X# X0 W( r" [9 R
+ H. _" [# F2 o- L. X$ T//############################################################2 u0 q1 ~8 v0 `
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_8|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_15);
9 L! a: g5 l5 f( S' vGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;: C6 j0 v# M( f
GPIO_Init(GPIOA, &GPIO_InitStructure);$ E$ ~" b" S! h
( c7 `1 K9 u1 r4 v
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10);
6 d: g4 i8 k7 E* Q; JGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;6 P) `* c3 L. F& C/ `( o% L
GPIO_Init(GPIOB, &GPIO_InitStructure);! i& E: M- v! E" [9 C9 c

, t9 @6 p, g5 a- Q; H$ jGPIO_InitStructure.GPIO_Pin = (GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);) Z% @0 Z! R. q" @1 w3 |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
6 @( j- a- J! f3 |GPIO_Init(GPIOC, &GPIO_InitStructure);
: y" [2 c% {7 p: ~' o8 w首先,想MOSI、SCK、CS、LED、RST这些管脚应该设置为推挽输出,TXD设置为复用输出,而IRQ、RXD、MISO设置浮空输入,什么都没接的管脚全都设置为下拉输入,而TESTI、TESO我一直不解是什么东东,开始就没管,而开始的时候MISO我也没怎么注意,设置成上拉输入(而不是浮空输入),反正大部分按照厂家提供的参考,我并没有照搬,测试效果一样,但功耗确是还有80-90uA,期间我找了好久没找到原因,给技术支持一看,原来是因为MISO没有设置成浮空输入,我是设置成了上拉输入,上拉电阻一直在消耗大约40uA的电流。。。 好吧,这是自己不够细心导致的,以后做低功耗的项目管脚配置是个大问题,不能再这么马虎了!!! 我将MISO设置成浮空输入之后,最低功耗还是有40+,离10uA的最低功耗还有段距离,到底是为什么呢?最后我发现6 C/ y/ L/ m- z! b% I
,该读卡芯片有个TESTIN/TESTOUT管脚,是用来测试用的,出厂后也就用不上了,我也一直以为这两个脚确实没什么用,就没接;可是我发现厂家提供的样板居然接了这两个脚,但是厂商也没说这两个脚接或不接会影响功耗啊,抱着试一试的心态,我我把TESTIN/TESTOUT两个管脚接到单片机上进行相应的配置,接下来是见证奇迹的时刻了,功耗居然真的、真的降到10uA了。。。。。。。。。。。 此处省略n个字& V2 L3 X( M3 S; V4 M5 A* x
这时候真的很激动,真的很想骂人啊,坑爹的厂家,为什么不给提示说这两个脚不接单片机会消耗电流呢?(也许是文档里面提到了,但是几百页的文档,还是全英文的,一堆堆的文字,我再看一遍,确实没有提到这两个管脚会有漏电流。)- R% e9 ^6 @  H
项目就这样完工了,中间最重要的是技术支持的强力支持,不然项目不能完工了,这个项目低功耗STM32方面难度不高,主要是读卡芯片上面的低功耗调试起来问题很多,还是人家原厂的出马才解决了问题,因为众多原因,不能公布该芯片的资料,包括该芯片怎么进入低功耗也无法公开,所以抱歉~~。
+ x- n# N3 b: M- I3 I0 S0 K' V关于STM32进入低功耗,我简单的总结了一下:
& t4 Y% F# ?- _) a1.管脚设置,这个很关键,还是跟你电路有关系,外加上拉、下拉电阻切记不能随便加6 f2 v% a9 w. @5 y( F* g. B
2.STM32的systick clock、DMA、TIM什么的,能关就全都关掉,STM32低功耗很简单,关键是外围电路功耗是关键+ J" s$ b  ~; Z: q* ~/ l' }
3.选择一个低功耗的LDO,这个项目用到的LDO功耗就很不错,静态功耗10uA都不到。
( g) D2 a% H! v. Y; w) d3 ]/ b8 A2 T4.确定STM32设置没问题,进入低功耗有好几种情况可以选择(睡眠、停机、待机),我还是推荐选择STOP模式,这个我觉的比较好是因为可以任意外部中断都可以唤醒,而且管脚可以保留之前的设置,进入停机模式的代码使用库函数自带的,就一句:! E3 y  Y3 H' {  g1 B* ?# }
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
, `0 A9 {  Q3 u/ `5 H% E1 }2 x! [意思是,在进入停机模式之前,也关掉电压调节器,进一步降低功耗,使用WFI指令(任意中断唤醒),但是经过测试,使用WFE(任事件唤醒)指令效果、功耗一模一样。  M( ?) C* ?& W1 d" o
最后一步是从STOP模式怎么恢复了,恢复其实也很简单,外部中断来了会进入中断函数,然后STM32就被唤醒,唤醒还要做一些工作,需要开启外部晶振(当然你也可以选择使用内部自带振荡器)、开启你需要的外设等等。/ _. \, Y' _' o4 C' q- P
 ; G  c* h/ E5 j6 K# i/ p1 d! y; w
总之,低功耗关键我觉得还是在于管脚配置,以及你对于外围电路的掌握。
赞 收藏 2 评论1 发布时间:2014-4-30 14:54

举报

1个回答
xiao zhang-2012 回答时间:2014-4-30 14:53:42

RE:分享一个低功耗项目小小心得

原帖是发在Openedv上面的,现在我自己转到与非网上面来。
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版