在前面一篇文章中,筆者主要介紹了自己的一些工作經(jīng)歷,跟真正的低功耗設(shè)計似乎扯不上半毛錢的關(guān)系。隨著電子產(chǎn)品的越來越普及,尤其是很多電子產(chǎn)品都用上了電池供電,既然用電池供電,那么似乎我們就不得不考慮電池的續(xù)航能力的問題,進而,迫使我們不得不考慮電子產(chǎn)品功耗的問題。那么究竟怎樣才算低功耗呢?小于100mA?小于1mA?小于10uA?似乎應(yīng)該加上應(yīng)用場合,這種數(shù)值才有意義。不管怎樣,低功耗的意思可以概括為越小越??!
在做這個溫度記錄儀之前,筆者壓根不怎么需要考慮功耗的問題,畢竟在一個大設(shè)備里,開關(guān)電源直接供電,控制板那100毫安以內(nèi)的電流,幾乎可以忽略不計了。然而,在做這個溫度記錄儀的時候,才發(fā)現(xiàn),100mA的電流經(jīng)得起多久的折騰?一塊500mAh的鋰電池,幾個小時就沒電了,更別說要用幾十天甚至半年到一年的時間了。
當然,降低功耗并不是純硬件或軟件就能實現(xiàn)的,很多時候,都是需要軟件和硬件的協(xié)同工作才能解決問題。比如,我們在做NTC測溫電路的時候,如果直接如下圖所示連接,那么實際上,計時在未進行AD采集的時候,改電路也一直在消耗電流,按照常溫狀態(tài)下來算,NTC的阻值為10K,那么這部分的電流消耗為:I=3.3V/(10K+10K)= 165uA。似乎看起來很小,但是,這只是電路中一部分的消耗,還有其他很多部分都有電流消耗,累加起來之后,就比這165uA大的多了。那么有沒有辦法讓這一部分電路的功耗降低呢?答案肯定是有的。
比如,我們可以在3.3V電源部分或者GND部分加一個開關(guān),并且通過一個IO口來直接控制這個開關(guān),在需要進行AD采樣的時候,把這個開關(guān)打開,采樣完成后,再把這個開關(guān)關(guān)閉,這樣一來,似乎就可以盡可能的減小這部分的開銷了。那么以在GND端加一個MOS管為例,如下圖所示:
這樣一來,我們就可以達到之前預(yù)期的目的了。當然,如果真如上這樣設(shè)計電路的話,無形中似乎也增加了成本,一個SI2302也需要一兩毛錢,一個電阻也是幾分錢,如果是幾K甚至幾十K的量的話,那么成本就不是一點點了。那么上述電路是不是還可以簡化一下呢?那是必須滴!實際上我們可以直接通過一個IO口來接到NTC的一端,畢竟按照之前計算的電流,也才微安級別的,就算忽略掉NTC的阻值,也有R1起到限流的作用,不用擔心燒壞IO口。那么,當需要采集AD的時候,直接將IO口拉低,就能實現(xiàn)電阻分壓了。
由此可見,降低功耗從硬件角度來說,就是需要找到所有可能的消耗電路的回路,一一確定哪些是可以通過軟件控制的方式來優(yōu)化功耗的,哪些是避免不了的,并給編程人員提供一個所有IO口狀態(tài)對功耗影響的關(guān)系,通常用簡單的表格說明一下高電平會怎樣,低電平會怎樣,懸浮會怎樣。做到這一點,基本上硬件的工作就告完成,剩下的就是軟件開發(fā)人員的發(fā)揮空間了。
說到軟件功耗優(yōu)化,簡單來說就是:能少工作的就少工作,能休眠的就休眠!以筆者做的這個溫度記錄儀為例,單片機型號選擇的是STC的STC8A8K64S4A12單片機,別問我為什么選擇這款單片機,因為筆者別的單片機不怎么會用,而且打樣時間又比較急,所以只能在自己熟悉的單片機中,選擇滿足要求的,價格又比較低的,功耗又是最低的來做了。整個項目中,主要就是RTC時鐘模塊、NTC測溫模塊、按鍵操作模塊、串口通信模塊、2.4G無線模塊、OLED顯示模塊、無線充電模塊等幾個部分。硬件部分,已經(jīng)盡可能的將功耗降到最低了,但是發(fā)現(xiàn),不管怎么操作,STC單片機正常工作的時候,電流還是有4-5mA,加上OLED顯示的話,也有2-3mA,2.4G模塊工作的時候電流更大,有30-40mA,這樣可真算不上低功耗啊,只能從軟件上來想辦法了!
首先,當然要將這個最大功耗的2.4G無線模塊的功耗解決。無他,最省事的讓他不工作的時候去睡覺了。根據(jù)這個模塊的使用手冊,只需將模塊的CS引腳拉高,該模塊就可以去睡大覺了。果然,這個無線模塊睡覺之后,整個板子的工作電流瞬間降到了10mA以內(nèi)了!
接下來,就要考慮OLED的問題了,雖然說,2-3mA的電流也不算很高,但是,那也是功耗啊,幾天下來也必將是一筆不小的開銷。當然,當時選擇OLED而并非筆段式LCD的原因也很簡單,OLED的界面可以隨意做呀,而且也比較好看,而筆段式LCD界面就只能固定死了,后面要修改的也比較麻煩。好吧,既然選擇了,也就不說那么多理由了,只能想辦法降功耗了。也沒有特別好的辦法,OLED的功耗也只能讓他不需要顯示的時候去睡覺來解決了。通過軟件設(shè)置一個休眠時間,然后在休眠時間到了后,然OLED乖乖去睡覺了,需要顯示的時候,再按一下按鍵來喚醒OLED。這樣,算是勉強解決了OLED功耗的問題了吧。
接下來,整個板子的功耗也就差不多在5mA左右了,再加上前面所說的AD采樣電路部分降低了一些功耗,剩下的主要就是MCU的功耗了。仔細翻閱了一下STC的手冊,得到了以下信息:
由此可見,MCU的功耗最低可以降到0.1uA以下!這樣的話,整個電路的功耗,基本可以做到1mA以下基本沒什么問題了。但是問題來了:在STOP模式下,此時的CPU和全部的外設(shè)都是停止工作的,這豈不是扯蛋么?全部停止工作了,OLED顯示怎么刷新?NTC溫度怎么獲???RTC時鐘怎么讀取?……一系列的問題來了!可能還是經(jīng)驗少,想破腦袋也沒想到好的辦法,無奈之下,只能求助了,慶幸的是,沒過多久,得到了一名網(wǎng)友的幫助,給我指點了一個比較好的思路:即,通過工作和休眠的時間比,來控制功耗。簡單來說就是,比如,設(shè)定1秒時間為參照,比如MCU完成一次一系列操作需要100ms,那么,就讓MCU工作完后,在剩下的900ms里去睡大覺,然后1秒時間到了,又把它喊起來繼續(xù)工作……如此循環(huán)。這樣一來,MCU的功耗便大大降低了!
在實現(xiàn)上述功能中,用到了STC單片機的掉電喚醒定時器。關(guān)于這個定時器的使用其實也很簡單,介紹什么的就不多說了,手冊上寫的很清楚,筆者就簡單介紹一下如何使用這個定時器。根據(jù)手冊,掉電喚醒定時器的定時時間如下計算:
那么,我們需要定時1秒左右的話,只需要將該定時器的計數(shù)次數(shù)設(shè)置在1999左右即可。于是,便有了下面的操作:
就這樣幾句代碼,MCU便可正常進入STOP模式,然后待掉電喚醒時間到,便又回到了正常工作模式。然后,我們只需要在while循環(huán)中,修改一下代碼,便可實現(xiàn)我們前面提到的功能。由于筆者項目中的功能比較復(fù)雜,下面就以一個簡單的例子來介紹一下吧。相信學單片機的小伙伴們對電燈程序再熟悉不過了吧,那么筆者就以最簡單的點燈程序為例吧:
很顯然,大家看慣了各種延時點燈程序,似乎很少看到這樣的一種點燈程序了吧?會不會有一種一臉懵逼的感覺?當時,毫無疑問,這確實也是一種點燈的手段。程序中,P30是用來控制LED的亮與滅,硬件電路就不用說了,相信大家猜都猜到了。上述代碼實現(xiàn)的功能就是,讓LED亮1秒鐘,然后再滅一秒,以此循環(huán)。實際上,MCU工作時只分別執(zhí)行了一條語句,即:P30 = 1;和P30 = 0;然后就進入了STOP模式,假設(shè)執(zhí)行語句的時間是1us,掉電喚醒定時器的時間是1秒,由此可見,MCU幾乎99.9%的時間都在睡大覺,自然功耗就大大降低了(此處忽略LED的功耗,只針對MCU功耗而言)。
好了,關(guān)于低功耗設(shè)計的思路就簡單介紹到這了,由于筆者能力有限,暫時未想到更好的辦法來降低功耗,更多的發(fā)揮空間就留個讀者了。如果你覺得這篇文章對你有幫助,別忘了點贊+打賞喲……
評論
查看更多