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 мкА | 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 Грабли
- Считать по 25 °C. При 85 °C Stop 2 у L476 берёт 15,4 мкА вместо 1,18. Бюджет батареи считают по той температуре, где прибор живёт.
- Охотиться за наноамперами, пока всплеск большой. Shutdown вместо Stop 2 выигрывает 0,12 года, а всплеск 1 мс вместо 5 — двадцать лет.
- Сохранять всё ОЗУ у U5. Stop 2 с полным ОЗУ — 20,5 мкА против 9,05 с одной SRAM2. Сохраняют только нужные банки.
- Ждать прежней частоты после Stop. Ядро просыпается на HSI16 или MSI; PLL и HSE заводят заново, иначе UART и таймеры считают не то.
- Входить в Stop 2 из Low-power run. RM0351: Stop 2 входят только из обычного режима Run.
- Shutdown без проверки питания. В нём не работает BOR; если питание проседает во сне, камень узнает об этом только после пробуждения.
- Принимать 115 200 бод в Stop 2 на LSE. LPUART на LSE — до 9600 бод; быстрее — только от HSI16, который включается на каждый кадр.
- Оставить выводы висеть в Standby и Shutdown. Выходы там отпускаются,
и ключ нагрузки может открыться сам. Уровни держат подтяжки: бит
APCи регистрыPWR_PUCRx,PWR_PDCRx. - Измерять с подключённым отладчиком. Отладчик держит домены включёнными, и ток сна с подключённым ST-Link не показателен — мерят без него, как в 10.8.
10а.8 Итоги
- L476 при 3 В, 25 °C: Stop 2 — 1,18 мкА (с RTC на кварце — 1,67), Standby — 150 нА, SRAM2 в Standby — плюс 236 нА, Shutdown — 64,1 нА. Пробуждение из Stop 2 — 7,3 мкс, из Standby — 14,3 мкс, из Shutdown — 256 мкс.
- F103: Stop — 14 мкА, Standby — 2 мкА при 3,3 В.
- При 85 °C Stop 2 у L476 — 15,4 мкА, в 13 раз больше.
- U585 течёт сильнее: Stop 2 — 9,05 мкА с одной SRAM2 и 20,5 мкА со всем ОЗУ, Stop 3 — 5,60 мкА, Standby — 0,36 мкА.
- Датчик из 10.8: от 4,46 года на F103 до 5,70 года на L476 в Shutdown — ток сна в 218 раз меньше, срок на 28 % больше. Всплеск 1 мс вместо 5 — 25,5 года.
- Режим выбирают полем
LPMSвPWR_CR1; после Stop ядро идёт на HSI16 или MSI (STOPWUCK). - В Stop 2 работают LPUART1 (до 9600 бод на LSE), LPTIM1, I2C3 и RTC.
Полные исходники
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 сами, а ядро будят раз в блок.