目的
最近在做一個(gè)低功耗的項(xiàng)目,需要一款超低功耗的mcu,整體運(yùn)行功耗不超過(guò)3mA(3.3v),同時(shí)要有i2c、spi以及uart通信,并且能承載一定的計(jì)算量,需要跑100hz以上的兩層卡爾曼濾波,最重要的是,要可以用Arduino系的庫(kù),為了非常方便開(kāi)發(fā)驗(yàn)證,所以還是基于A(yíng)TMEGA328P進(jìn)行低功耗探索,看看到底能做到多低的運(yùn)行功耗
硬件準(zhǔn)備
電壓將為3.3v,頻率降為8MHz,由于我手頭上有一塊Arduino Pro Mini的小板子,所以基于這個(gè)板子進(jìn)行改造,如果不是同款板子,也可以參照著進(jìn)行改造,只要都是ATMEGA328P芯片就行
-
拆除LDO(低壓差穩(wěn)壓器)和LED,我板子上的LDO大概會(huì)消耗50uA的電流
-
使用usbisp修變板子的熔絲位為:
0xFDDAFF,熔絲位參照Arduino官方板子Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328P的設(shè)置,官方板子配置在:
用porgisp軟件修改熔絲位:
我用的usbisp:
Arduino官方最低支持的就是3.3v 8Mhz的頻率,ATMEGA328P還可以通過(guò)修改熔絲位來(lái)調(diào)整是否使用外部晶振,從而達(dá)到更低功耗,但修改后就得自己寫(xiě)bootloader了,所以硬件部分就只能優(yōu)化到這了,如果大神們還有更低的方案歡迎評(píng)論區(qū)留言
軟件修改
在做完硬件修改后,整體功耗在8.1mA左右,跑我的算法可以到1000hz左右,我的傳感器只需要100hz刷新即可,算力有點(diǎn)浪費(fèi)了
- 引入avr/power庫(kù),
#include <avr/power.h>,通過(guò)clock_prescale_set函數(shù)進(jìn)行降頻,對(duì)應(yīng)的電流值如下:
/**
* clock_div_1 8.1 mA
* clock_div_2 5 mA
* clock_div_4 3.3 mA
* clock_div_8 2.2 mA
* clock_div_16 1.6 mA
* clock_div_32 1.3 mA
*/
clock_prescale_set(clock_div_8);
由于我需要保證100hz刷新,所以選擇clock_div_8,最后刷新率在120hz左右,電流在2.2mA左右,加上外圍電路的消耗,總消耗也在3mA以?xún)?nèi),達(dá)標(biāo)
- 調(diào)整時(shí)間計(jì)算,由于通過(guò)avr的庫(kù)降頻了,Arduino的庫(kù)函數(shù)并沒(méi)有對(duì)應(yīng)做處理,也就是說(shuō)整體的運(yùn)算速度下降了,原本的時(shí)間間隔也被拉長(zhǎng)了,比如最常用的
millis()和delay()函數(shù)已經(jīng)不能對(duì)應(yīng)上實(shí)際發(fā)生的時(shí)間了,因?yàn)檫@些時(shí)間相關(guān)的函數(shù)都是通過(guò)定時(shí)器來(lái)計(jì)算時(shí)間的,定時(shí)器降頻了,所以時(shí)間變慢了,要回到正確的時(shí)間上必須對(duì)時(shí)間進(jìn)行處理,比如我是clock_div_8,那么millis()需要乘8,delay()需要除以8



