Embedded HandbookПриложения
Все разделы › II. Ядро и системные механизмы
STM32L476, STM32U585, STM32F103 · уровень средний · 9 мин чтения
Открыть в интерактивном справочнике

10а. Малое потребление на L4 и U5: Stop 2, Stop 3, Standby с SRAM2, Shutdown

Раздел 10 разобрал три режима сна F103 — Sleep, Stop и Standby — и G0 с его полем LPMS. Серии, сделанные для батареек, — L4 и U5 — добавляют ступени: Stop 2, Stop 3, Standby с сохранением части ОЗУ, Shutdown. На бумаге ток сна падает в сотни раз. Здесь — сколько именно, что за это платят и почему батарейка датчика из 10.8 от этого живёт лишь на четверть дольше.

Все токи — типовые значения таблиц даташитов STM32L476 (DS10198), STM32U585 (DS13086) и STM32F103 (таблица 16) при 25 °C; режимы и биты — RM0351 и RM0456. Листинги собраны armclang для L476 и U585; срок батареи пересчитан на ПК. На плате эти числа не мерились — порядок их проверки описан в 10.8.

Как это называется в документации

Оригинал Перевод
Stop 0 / Stop 1 / Stop 2 / Stop 3 ступени режима Stop: чем выше номер, тем больше выключено
Standby with SRAM2 retention Standby с сохранением SRAM2
Shutdown выключение: остаётся только резервный домен
low-power mode selection (LPMS) поле выбора режима сна
wakeup clock (STOPWUCK) генератор, на котором ядро просыпается из Stop
LPUART, LPTIM UART и таймер, работающие в Stop на часовом кварце
wakeup time время от события до первой команды программы
ultra-low-power сверхмалое потребление

10а.1 Лестница режимов L476

Режим Ток сна, 3 В Что сохраняется Пробуждение до первой команды
Stop 2 1,18 мкА ОЗУ, регистры, выводы 7,3 мкс (на HSI16, код во Flash)
Stop 2 + RTC на часовом кварце 1,67 мкА то же и часы то же
Standby 150 нА только резервный домен 14,3 мкс, но через сброс
Standby + RTC на часовом кварце 652 нА резервный домен и часы то же
Standby + SRAM2 150 + 236 нА и SRAM2 (32 КБ) 14,3 мкс, через сброс
Shutdown 64,1 нА резервный домен, без детектора питания 256 мкс, через сброс

Для сравнения у F103 (раздел 10): Stop с экономичным регулятором — 14 мкА при 3,3 В, Standby — 2 мкА. Stop 2 у L476 в двенадцать раз экономнее Stop у F103 и при этом сохраняет всё: ОЗУ, регистры периферии, состояние выводов. Программа продолжается со следующей строки, как после Stop у F103.

Standby и Shutdown — это сброс на выходе: программа начинает с начала, и всё нужное должно лежать в резервных регистрах или, у L4, в SRAM2 — её можно оставить живой за 236 нА. Shutdown отключает даже детектор просадки питания: пока камень спит, BOR не работает.


10а.2 Температура: 1,18 мкА только на столе

Токи сна — это утечки транзисторов, а утечки растут с температурой экспоненциально. Та же строка таблицы 45 для Stop 2 при 3 В:

Температура 25 °C 55 °C 85 °C 105 °C
Stop 2, типовой 1,18 мкА 3,97 мкА 15,4 мкА 36,4 мкА
Stop 2, максимум 2,8 мкА 10 мкА 39 мкА 91 мкА

При 85 °C — в тринадцать раз больше, чем на столе. Датчик в уличном щитке летом, в машине, рядом с двигателем считают по горячей колонке. Для примера из 10.8 это 4,37 года вместо 5,58 — при том же коде.


10а.3 U585: новее — не значит экономнее

U585 — большой камень: 2 МБ Flash, 786 КБ ОЗУ, TrustZone. У него есть Stop 3, которого нет у L4, но ток сна выше, потому что утечек больше:

Режим U585 (3 В) Ток сна
Stop 2, живы SRAM2 8 КБ и кэш команд 9,05 мкА
Stop 2, живо всё ОЗУ 20,5 мкА
Stop 3, живы SRAM2 8 КБ и кэш команд 5,60 мкА
Stop 3, живо всё ОЗУ 13,0 мкА
Standby 0,36 мкА

Каждый килобайт сохранённого ОЗУ течёт. Stop 2 с полным ОЗУ у U585 берёт в семнадцать раз больше, чем у L476. Если прибору нужны микроамперы, а не TrustZone и мегабайт памяти, его делают на L4; у U5 сохраняют только те банки ОЗУ, в которых действительно что-то лежит.


10а.4 Батарейка: всплеск съедает всё

Датчик из 10.8: раз в секунду просыпается на 5 мс и берёт 10 мА, батарея 2500 мА·ч. Средний ток — по той же формуле:

Ток сна на логарифмической шкале: F103 Stop 14 мкА, U585 Stop 2 9,05, U585 Stop 3 5,6, L476 Stop 2 1,18, U585 Standby 0,36, L476 Standby 0,15, L476 Shutdown 0,064 мкА; все они меньше 50 мкА, которые в среднем берёт всплеск 5 мс по 10 мА раз в секунду

Сон Ток сна Средний ток Срок батареи
F103 Stop 14 мкА 63,93 мкА 4,46 года
U585 Stop 2 9,05 мкА 59,00 мкА 4,84 года
U585 Stop 3 5,60 мкА 55,57 мкА 5,14 года
L476 Stop 2 1,18 мкА 51,17 мкА 5,58 года
L476 Standby 150 нА 50,15 мкА 5,69 года
L476 Shutdown 64,1 нА 50,06 мкА 5,70 года

Ток сна упал в 218 раз, а срок вырос с 4,46 до 5,70 года — на 28 %. Всплеск 5 мс × 10 мА раз в секунду сам по себе даёт 50 мкА среднего тока, и никакой режим сна его не уменьшит. Стоит укоротить всплеск до 1 мс — и L476 в Stop 2 даёт 11,18 мкА среднего и 25,5 года; на таком сроке упираются уже в саморазряд батарейки, а не в камень.

Отсюда порядок работы, тот же, что в 10.8: сначала ужать активную часть — меньше тактов, короче замер, реже пробуждения, — потом выбирать режим сна. Standby вместо Stop 2 выигрывает здесь 0,11 года, но превращает каждое пробуждение в сброс с инициализацией, а она сама удлиняет всплеск.


10а.5 Вход в Stop 2, Standby с SRAM2 и Stop 3

У L4 режим выбирают полем LPMS в PWR_CR1, как у G0 в 10.9, а входят тем же WFI при установленном SLEEPDEEP:

void stop2_enter(void)
{
    RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
    RCC->CFGR |= RCC_CFGR_STOPWUCK;                 /* проснуться на HSI16, а не на MSI */
    PWR->CR1 = (PWR->CR1 & ~PWR_CR1_LPMS) | PWR_CR1_LPMS_STOP2;
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __DSB();
    __WFI();                                        /* спим; будит RTC или LPUART1 */
    SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;             /* дальше WFI — снова обычный Sleep */
}

void standby_keep_sram2(void)
{
    RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
    PWR->CR3 |= PWR_CR3_RRS;                        /* SRAM2 живёт в Standby: +236 нА */
    PWR->SCR = PWR_SCR_CWUF;                        /* сбросить старые флаги пробуждения */
    PWR->CR1 = (PWR->CR1 & ~PWR_CR1_LPMS) | PWR_CR1_LPMS_STANDBY;
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __DSB();
    __WFI();                                        /* выход — через сброс */
}

После Stop 2 ядро просыпается не на прежней частоте, а на внутреннем генераторе: бит STOPWUCK выбирает HSI16 вместо MSI. PLL и внешний кварц после пробуждения включают заново, как после Stop у F103.

У U585 то же поле LPMS, но значений больше: 011 — Stop 3 (RM0456, описание PWR_CR1):

void stop3_enter(void)
{
    RCC->AHB3ENR |= RCC_AHB3ENR_PWREN;
    RCC->CFGR1 |= RCC_CFGR1_STOPWUCK;               /* проснуться на HSI16 */
    PWR->CR1 = (PWR->CR1 & ~PWR_CR1_LPMS) | PWR_CR1_LPMS_0 | PWR_CR1_LPMS_1;   /* 011 — Stop 3 */
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __DSB();
    __WFI();
    SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
}

10а.6 Кто работает во сне: LPUART и LPTIM

В Stop 2 остановлены все такты ядра, но несколько блоков сделаны так, чтобы жить без них. LPUART1 на часовом кварце 32 768 Гц принимает до 9600 бод (RM0351) и будит ядро по приходу байта; для большей скорости его тактируют от HSI16 — в Stop он сам включает генератор на время кадра и выключает его, если кадр не адресован прибору. LPTIM1 считает импульсы или время от LSE, RTC будит по будильнику. Так прибор слушает линию или считает импульсы счётчика воды, потребляя единицы микроампер, и просыпается целиком только по делу.

Обычные USART, SPI, I²C (кроме I2C3), таймеры и АЦП в Stop 2 не работают: им нужен тактовый сигнал, которого нет. Если прибор должен принимать на 115 200 бод — это Stop 0 или Sleep, а в Stop 2 — только LPUART1 от HSI16: генератор включается на время каждого кадра, и ток сна растёт.


10а.7 Грабли


10а.8 Итоги

Полные исходники

lp10a.c — вход в Stop 2 и в Standby с сохранением SRAM2 у L476 и в Stop 3 у U585.

/* 10а: вход в Stop 2 и в Standby с сохранением SRAM2 (L476), Stop 3 (U585).
   Собирается armclang для STM32L476 и STM32U585 (проверка _verify/lp10a_check.py). */
#include <stdint.h>

#if defined(STM32L476xx)
void stop2_enter(void)
{
    RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
    RCC->CFGR |= RCC_CFGR_STOPWUCK;                 /* проснуться на HSI16, а не на MSI */
    PWR->CR1 = (PWR->CR1 & ~PWR_CR1_LPMS) | PWR_CR1_LPMS_STOP2;
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __DSB();
    __WFI();                                        /* спим; будит RTC или LPUART1 */
    SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;             /* дальше WFI — снова обычный Sleep */
}

void standby_keep_sram2(void)
{
    RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
    PWR->CR3 |= PWR_CR3_RRS;                        /* SRAM2 живёт в Standby: +236 нА */
    PWR->SCR = PWR_SCR_CWUF;                        /* сбросить старые флаги пробуждения */
    PWR->CR1 = (PWR->CR1 & ~PWR_CR1_LPMS) | PWR_CR1_LPMS_STANDBY;
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __DSB();
    __WFI();                                        /* выход — через сброс */
}
#endif

#if defined(STM32U585xx)
void stop3_enter(void)
{
    RCC->AHB3ENR |= RCC_AHB3ENR_PWREN;
    RCC->CFGR1 |= RCC_CFGR1_STOPWUCK;               /* проснуться на HSI16 */
    PWR->CR1 = (PWR->CR1 & ~PWR_CR1_LPMS) | PWR_CR1_LPMS_0 | PWR_CR1_LPMS_1;   /* 011 — Stop 3 */
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    __DSB();
    __WFI();
    SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
}
#endif

Дальше: раздел 10б «LPBAM на STM32U5» — таймер, АЦП и контроллер пересылок работают в Stop 2 сами, а ядро будят раз в блок.

Открыть в интерактивном справочнике