您的位置 首页 硬件

共享一个低功耗项目小小心得

前两个月在公司做了一个低功耗项目,现在功耗最低10uA不到,平均功耗40uA左右,算是达标了。因为是公司产品,就不方便贴代码、原理图

前两个月在公司做了一个低功耗项目,现在功耗最低10uA不到,均匀功耗40uA左右,算是合格了。由于是公司产品,就不便利贴代码、原理图了,该产品是一个小模块,能够便利的嵌入到各种体系里边。跟原子哥他们卖的NRF2401相似,是一个读卡器。

做这个项目中心也请了技术支撑,由于外围电路芯片的功耗一向降不下来,通过与对方的重复沟通,对方供给了低功耗的测验成果、硬件计划、软件计划,通过修正测验,终究成为咱们的产品,功耗比较满足。
硬件计划挑选的是STM32,外加某公司的读卡芯片。前期完成了读卡等功能的开发,最终一项开发内容是最艰巨也是最困难的—低功耗。在开发过程中,从硬件规划上不断裁剪元器件,软件上不断精简代码,功耗最低都保持在3-4mA。

电路规划上,只用到了一个LED、串口1、一个模仿SPI、一个中止线、一个读卡芯片RESET线,硬件上就只剩余这么点东西了,这个时分我选用的是待机形式,运用的是读卡芯片的中止接PA0唤醒STM32,在此之前要先使得读卡芯片进入低功耗、然后STM32进入低功耗,这一步完成了,形似没什么问题,功耗的确从几十mA骤降到3mA左右,开端还挺满足的,可是测验厂商供给的样板,功耗却只要几十uA,有点抑郁了。为什么会这样?重复查看硬件、程序,都找不出原因,并且这个时分的作业作用很烂,底子就不能唤醒,所以我就怀疑是读卡芯片一端低功耗有问题,由于我将PA0脚直接短接VCC,这样就能够发生一个边缘触发STM32唤醒了,可是用读卡芯片无法唤醒,所以我怀疑是读卡芯片的RESET脚电平不对,经查看,的确是由于RESET脚加了上拉电阻,读卡芯片是高电平复位,在STM32进入待机后,管脚全都浮空了,导致RESET被拉高,一向在复位;我去掉上拉电阻,觉得很有期望处理问题了,可是测验成果是:有时分能唤醒,有时分不能,我仔细一想莫非是由于STM32待机后管脚电平不确认,导致读卡芯片RESET脚电平不定,而作业不正常,看样子只要换用其他计划了。后边的确验证了我的主意,运用STOP形式后,唤醒问题引刃而解。
就在要害时刻,芯片原厂火种送炭,送来急需的技术支撑材料,一个包含低功耗源代码,赶忙拿过来测验,先研读下代码,运用的是STOP形式,而不是待机形式,运用的是恣意外部中止唤醒,功耗低制40uA,这个时分就适当激动啊,从速下载测验啊,成果功耗的确降了,但仍是有1mA,更人家一比多了几十倍啊。。。
我榜首反应是硬件不对,通过测验修正,首要找到榜首个原因,读卡芯片RESET管脚上拉电阻又给焊上去了…,拆掉后功耗骤降到几百uA,仍是不可。。 测验过程中,为了去掉LDO的搅扰,整板选用3.3V供电,可是后边通过测验,LDO的功耗其实也只要5uA不到,这LDO功耗值得赞一个;尽管成果仍是没到达预期,可是看到了期望,成功就在眼前啊。
为此我重复看了技术支撑供给的程序,发现他们的STM32的一切管脚都的设置都有所讲究:(由于公司保密准则,代码中删去掉了关于该读卡芯片的前缀信息等)

GPIO_InitTypeDef GPIO_InitStructure;

/* GPIOA Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* GPIOB Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* GPIOC Periph clock enable */
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//####################################################
//USART1 Port Set
//TXD
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//RXD
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);

//RST output pushpull mode
GPIO_InitStructure.GPIO_Pin = TRST;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(PORT1, &GPIO_InitStructure);
//IRQ input pull-up mode
GPIO_InitStructure.GPIO_Pin = TIRQ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(PORT1, &GPIO_InitStructure);
//MISO input pull-up mode
GPIO_InitStructure.GPIO_Pin = MISO;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(PORT2, &GPIO_InitStructure);
//NSS,SCK,MOSI output pushpull mode
GPIO_InitStructure.GPIO_Pin = (NSS|SCK|MOSI);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(PORT2, &GPIO_InitStructure);
//############################################################################
//TEST Port set
//TESTO input pushpull mode
GPIO_InitStructure.GPIO_Pin = TESTO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(TEST_PORT, &GPIO_InitStructure);
//############################################################################
//TEST Port set
//TESTI output pushpull mode
GPIO_InitStructure.GPIO_Pin = TESTI;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(TEST_PORT, &GPIO_InitStructure);
//############################################################################
//LED Port Set
//LED output pushpull mode
GPIO_InitStructure.GPIO_Pin = LED;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(LED_PORT, &GPIO_InitStructure);

//############################################################
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);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA, &GPIO_InitStructure);

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);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOC, &GPIO_InitStructure);
首要,想MOSI、SCK、CS、LED、RST这些管脚应该设置为推挽输出,TXD设置为复用输出,而IRQ、RXD、MISO设置浮空输入,什么都没接的管脚全都设置为下拉输入,而TESTI、TESO我一向不解是什么东东,开端就没管,而开端的时分MISO我也没怎样留意,设置成上拉输入(而不是浮空输入),横竖大部分依照厂家供给的参阅,我并没有照搬,测验作用相同,但功耗确是还有80-90uA,期间我找了良久没找到原因,给技术支撑一看,本来是由于MISO没有设置成浮空输入,我是设置成了上拉输入,上拉电阻一向在耗费大约40uA的电流。。。 好吧,这是自己不行仔细导致的,今后做低功耗的项目管脚装备是个大问题,不能再这么大意了!!! 我将MISO设置成浮空输入之后,最低功耗仍是有40+,离10uA的最低功耗还有段间隔,到底是为什么呢?最终我发现

,该读卡芯片有个TESTIN/TESTOUT管脚,是用来测验用的,出厂后也就用不上了,我也一向认为这两个脚的确没什么用,就没接;可是我发现厂家供给的样板竟然接了这两个脚,可是厂商也没说这两个脚接或不接会影响功耗啊,抱着试一试的心态,我我把TESTIN/TESTOUT两个管脚接到单片机进步行相应的装备,接下来是见证奇观的时刻了,功耗竟然真的、真的降到10uA了。。。。。。。。。。。 此处省掉n个字
这时分真的很激动,真的很想谩骂啊,坑爹的厂家,为什么不给提示说这两个脚不接单片时机耗费电流呢?(也许是文档里边说到了,可是几百页的文档,仍是全英文的,一堆堆的文字,我再看一遍,的确没有说到这两个管脚会有漏电流。)
项目就这样竣工了,中心最重要的是技术支撑的强力支撑,否则项目不能竣工了,这个项目低功耗STM32方面难度不高,主要是读卡芯片上面的低功耗调试起来问题许多,仍是人家原厂的出马才处理了问题,由于很多原因,不能发布该芯片的材料,包含该芯片怎样进入低功耗也无法揭露,所以抱愧~~。
关于STM32进入低功耗,我简略的总结了一下:
1.管脚设置,这个很要害,仍是跟你电路有联系,外加上拉、下拉电阻牢记不能随意加
2.STM32的systick clock、DMA、TIM什么的,能关就全都关掉,STM32低功耗很简略,要害是外围电路功耗是要害
3.挑选一个低功耗的LDO,这个项目用到的LDO功耗就很不错,静态功耗10uA都不到。
4.确认STM32设置没问题,进入低功耗有好几种状况能够挑选(睡觉、停机、待机),我仍是引荐挑选STOP形式,这个我觉的比较好是由于能够恣意外部中止都能够唤醒,并且管脚能够保存之前的设置,进入停机形式的代码运用库函数自带的,就一句:

PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
意思是,在进入停机形式之前,也关掉电压调节器,进一步下降功耗,运用WFI指令(恣意中止唤醒),可是通过测验,运用WFE(任事情唤醒)指令作用、功耗一模相同。
最终一步是从STOP形式怎样康复了,康复其实也很简略,外部中止来了会进入中止函数,然后STM32就被唤醒,唤醒还要做一些作业,需求敞开外部晶振(当然你也能够挑选运用内部自带振荡器)、敞开你需求的外设等等。

总归,低功耗要害我觉得仍是在于管脚装备,以及你关于外围电路的把握。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/yingjian/258969.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部