嵌入式與裸機

低功耗睡眠模式(sleep modes)與中斷喚醒

想想你怎麼省手機電量:把螢幕調暗、讓它睡眠、再關機——每深一層省更多電卻要更久才能回來。微控制器把同樣的概念內建在矽片裡。低功耗睡眠模式是 MCU 在無事可做時能進入以省電的硬體狀態,從瞬間就能醒來的淺打盹,到幾乎不耗電卻醒得較慢(且記得較少)的深層冬眠都有。

具體來說,典型 MCU 提供一道模式的階梯(名稱因供應商而異)。在淺層「睡眠」模式裡,CPU 時鐘被停止,所以它不執行任何指令、耗電大減,但週邊與 RAM 仍存活,於是晶片能在一微秒內醒來並從暫停處恰好繼續。在較深的「停止」模式裡,更多時鐘與電路被關閉(功耗更低、醒得更慢,但 RAM 內容通常保留)。在最深的「待機」或關機模式裡,幾乎一切都斷電——電流可降到微安甚至奈安——但 RAM 通常喪失,醒來更像一次重置。讓睡眠有用的關鍵是「中斷喚醒」:睡前你先武裝一個中斷來源(按鈕、計時器、收到的位元組、外部接腳),然後發出睡眠指令;CPU 停住,當那個中斷觸發時,硬體喚醒 CPU,它執行 ISR 後繼續。所以慣用法是:把你的工作設計成中斷驅動,主迴圈除了睡眠什麼都不做,只在真有工作時讓中斷喚醒你——晶片大半輩子都在睡。在 Cortex-M 上,WFI(等待中斷)指令是基本的睡眠,而 SysTick 或一個低功耗計時器是常見的喚醒源。

它對電池供電裝置至關重要:一個 99.9% 時間在睡、只在計時器上短暫醒來的感測器,能靠一顆鈕扣電池運作數年,而同一個感測器若忙碌迴圈幾天就沒電。誠實的取捨:較深的模式省更多卻付出更多喚醒延遲、且可能喪失狀態(RAM、週邊設定),所以你必須在喚醒時重新初始化;並非每個週邊都能從每種模式喚醒晶片(你必須在參考手冊查每種模式哪些喚醒源有效);而一個典型的耗電臭蟲是讓某個週邊或時鐘繼續跑、或在迴圈裡忙碌等待,而不是真正進入睡眠模式——空轉的「閒置」程式碼仍吃滿電。實際量測電流;別用猜的。

// 大半時間閒置;只在中斷觸發時喚醒。 arm_wakeup_interrupt(BUTTON_IRQn); // 按鈕可以喚醒我們 for (;;) { if (work_pending) handle_work(); __WFI(); // 「等待中斷」:停住 CPU、省電。 // 按鈕(或計時器)ISR 執行,然後我們從這裡繼續。 } // 較深的模式省更多,但可能喪失 RAM 且醒得較慢。

WFI 停住 CPU 直到武裝的中斷喚醒它;裝置在事件之間睡眠,只在真有工作時耗電。

常見的耗電元兇是靠忙碌迴圈「閒置」而非進入真正睡眠模式的程式碼——空轉吃滿電。較深的模式省更多卻可能喪失 RAM 並限制哪些中斷能喚醒你,所以要查每種模式的喚醒源。

又稱
sleep modesstop modestandby modewake-on-interrupt睡眠模式停止模式中斷喚醒