1電源管理
上電復(fù)位 POR 參考
掉電復(fù)位 PDR
欠壓復(fù)位
使能BOR后POR和PDR的門限將被忽略,轉(zhuǎn)而使用BOR設(shè)置的門限,BOR門限 在 option bytes中配置
| 模式 | 門限 |
|---|---|
| 1 | 1.8V上電 1.65V斷電 |
| 2 | 2.1V上電 2.0V斷電 |
| 3 | 2.4V上電 2.3V斷電 |
| 4 | 2.7V上電 2.6V斷電 |
| 5 | 2.9V上電 2.8V斷電 |
- 可編程電壓監(jiān)控 PVD
軟件控制,監(jiān)控VDD,門限可以設(shè)置在1.8-3.1間,100mV為間隔,當PVD大于或者小于門限則產(chǎn)生一個外部中斷.
2低功耗模式
2.1低功耗運行模式
內(nèi)核和外設(shè)都可以保存運行狀態(tài),需要配置內(nèi)部電源變換器工作在低功耗模式下,系統(tǒng)時鐘必須設(shè)置在128KHz一下,可以使用MSI作為系統(tǒng)時鐘,內(nèi)核供電必須選擇供電范圍2(1.5V),并且關(guān)閉動態(tài)電壓調(diào)節(jié)功能
2.2睡眠模式
內(nèi)核停止運行,外設(shè)保持運行.
通過特殊指令進入睡眠模式.
WFI由中斷喚醒,任意的NVIC識別到外設(shè)中斷都可以喚醒內(nèi)核
WFE由事件喚醒,被配置為事件模式的EXTI中斷喚醒內(nèi)核
2.3低功耗睡眠模式
內(nèi)核停止運行,外設(shè)保存運行
2.4停止模式
內(nèi)核停止,內(nèi)核電源范圍內(nèi)的時鐘都停止,晶振也禁止,SRAM和寄存器內(nèi)容保留。啟動時需要重新配置時鐘,并且清除標志位,喚醒后程序繼續(xù)之前的運行。
2.5待機模式
電源內(nèi)部變換器關(guān)閉、內(nèi)核電源范圍內(nèi)全部斷電,晶振被禁止,SRAM和寄存器不保留,RTC寄存器和備份寄存器保留。在待機模式下所有IO都保存高阻態(tài),除了復(fù)位、RTC報警輸出引腳、喚醒引腳,功耗典型值為1ua,但是如果對接了外部電路,不用配置引腳的優(yōu)勢也就變成了劣勢,就如同我測試的SPI設(shè)備,待機模式的時候MOSI和SCK實際上是有電流的,功耗降不下去,這種時候選擇停止模式,來單獨配置IO口才行。
2.6 總結(jié)

3 代碼與測試
測試硬件: 將STM32L151開發(fā)板上的多余器件全部去除
低功耗初始化函數(shù)
void low_power_init()
{
/* Enable Ultra low power mode */
HAL_PWREx_EnableUltraLowPower();
/* Enable the fast wake up from Ultra low power mode */
HAL_PWREx_EnableFastWakeUp();
HAL_PWR_DisablePVD();
}
3.1待機模式(standby)
進入待機模式的代碼,使用HAL庫中的stm32l1xx_hal_pwr.c文件,下列中如果不進行清除標志位,則設(shè)備在第二次進入待機模式后將自動被喚醒。
void enter_standby_wakup()
{
if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
{
/* Clear Standby flag */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
}
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
HAL_PWR_EnterSTANDBYMode();
}
進入低功耗后所有引腳都會被置為高阻態(tài),正常運行時功耗在10幾mA,進入standby后電流下降到1~5uA左右,通過PA0上拉喚醒,該引腳也無需配置
3.2停止模式
代碼使用了一個啟動后常亮的引腳和一個外部中斷按鍵,前者用于判斷在進入停機模式后,引腳狀態(tài),結(jié)果是引腳仍然處于之前的狀態(tài),也就是寄存器被保持了。后者用于退出停機模式。
//該模式在退出時候必須重新配置時鐘
//該模式需要在中斷回調(diào)中添加
//__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
void enter_stop_exti()
{
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_Config();
}
如果單單進入停止模式,外部引腳是有可能消耗電量的,可用如下代碼將全部引腳置為浮空輸入,并且關(guān)閉GPIO時鐘
GPIO_InitTypeDef GPIO_InitStructure = {0};
/* Enable GPIOs clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */
GPIO_InitStructure.Pin = GPIO_PIN_All;
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);
/* Disable GPIOs clock */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_GPIOH_CLK_DISABLE();
但并不是所有引腳都應(yīng)該配置成浮空輸入,對于一些特殊引腳可用在關(guān)閉時鐘前進行單獨配置,例如
~~~
GPIO_InitStructure.Pin = GPIO_PIN_7;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
~~~
停止模式并不會重啟程序,被喚醒后將會繼續(xù)執(zhí)行之前的代碼,也就是說引腳是應(yīng)該被回復(fù)成被應(yīng)用的狀態(tài),我們可以在將所有引腳配置成為浮空輸入之前保存一下GPIO寄存器的值,然后在退出停止模式后,將保存的值再賦值給寄存器。
//讀取當前GPIO狀態(tài)
GPIO_TypeDef gpio_a;
GPIO_TypeDef gpio_b;
GPIO_TypeDef gpio_c;
GPIO_TypeDef gpio_h;
rt_memcpy(&gpio_a,GPIOA,sizeof(GPIO_TypeDef));
rt_memcpy(&gpio_b,GPIOB,sizeof(GPIO_TypeDef));
rt_memcpy(&gpio_c,GPIOC,sizeof(GPIO_TypeDef));
rt_memcpy(&gpio_h,GPIOH,sizeof(GPIO_TypeDef));
//復(fù)位IO
rt_memcpy(GPIOA,&gpio_a,sizeof(GPIO_TypeDef));
rt_memcpy(GPIOB,&gpio_b,sizeof(GPIO_TypeDef));
rt_memcpy(GPIOC,&gpio_c,sizeof(GPIO_TypeDef));
rt_memcpy(GPIOH,&gpio_h,sizeof(GPIO_TypeDef));
3.3 睡眠模式
睡眠模式能夠被任意中斷喚醒,也就是滴答定時器中斷也能喚醒它,下列示例代碼是在rtt系統(tǒng)下,在空閑回調(diào)里面添加進入休眠模式
void enter_sleep()
{
/*Suspend Tick increment to prevent wakeup by Systick interrupt.
Otherwise the Systick interrupt will wake up the device within 1ms (HAL time base)*/
//HAL_SuspendTick();
/* Enter Sleep Mode , wake up is done once Key push button is pressed */
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
/* Resume Tick interrupt if disabled prior to sleep mode entry*/
//HAL_ResumeTick();
}
void low_pwoer_hook_cb()
{
//該回調(diào)未關(guān)閉滴答
enter_sleep();
}
void low_power_set_idle_hook()
{
rt_thread_idle_sethook(low_pwoer_hook_cb);
}
4 官方文檔翻譯
- 芯片功耗典型值
待機模式:0.28uA
待機模式+RTC:1.11uA
停止模式:0.44uA
停止模式+RTC:1.38uA
低功耗運行模式:10.9uA
運行模式: 185uA/MHz
5 實際測試圖
下圖為STM32L151進入停止模式 和 SX1278進入休眠模式的功耗圖
