Как добиться низкого энергопотребления с STM32L476?
Сделать плату с током менее 1 мкА несложно. В прошлом году я делал маленький водяной счётчик на базе L476, в итоге получилось 0.8 мкА. 50 000 штук в серийном производстве — ни одного сбоя. Если следовать этой процедуре, проблем быть не должно:
-
Организуйте питание
- Для 3.3 В используйте LDO с током покоя 1 мкА (я использовал серию XC6206), не берите те, у которых утечка в режиме покоя измеряется в миллиамперах, например 1117.
- Все датчики, 485, Flash подключаются через MOSFET-ключи. Перед входом в режим низкого энергопотребления отключайте их полностью. Не верьте в «2 мкА в режиме ожидания» из datasheet — на практике минимум 50 мкА.
-
Проработайте все GPIO
- Аналоговые входы: устанавливайте
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;— это самый экономичный режим. - Цифровые входы: либо подключайте внутренний подтяг, либо внешний 100 кОм, но ни в коем случае не оставляйте их неподключёнными.
- Цифровые выходы: устанавливайте чёткое состояние согласно уровням периферии. Даже если периферия обесточена, вывод должен быть 0, иначе 3 В через защитный диод будет питать периферию.
- NRST, BOOT0: вместо 10 кОм подтягивайте 1 МОм, сэкономите 300 мкА.
- Аналоговые входы: устанавливайте
-
Оставьте только LSE в дереве тактирования
- В CubeMX отключите HSI/HSI16/PLL, MSI тоже не оставляйте.
- Для пробуждения RTC используйте только LSE, не LSI. При включённом LSI потребление сразу возрастает до 1 мкА.
-
Используйте STOP2, а не Standby
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);— после пробуждения RAM сохранится, не нужно повторно инициализировать.- Источники пробуждения: RTC и один GPIO по фронту. Не используйте UART для пробуждения, возможна зависание.
-
Отключите всю периферию
- Для I²C/SPI/UART сначала выполните
__HAL_RCC_*_FORCE_RESET(), затем__HAL_RCC_*_RELEASE_RESET(), чтобы сбросить регистры в исходное состояние. Иначе IO может застрять в низком состоянии, и вы получите 179 мкА (см. официальную тему ST). - ADC, COMP, OPAMP: сначала
HAL_*_DeInit(), затем отключите тактирование. - DMA, USB, CRC: отключите тактирование. Не верьте в «автоматическое отключение» — каждая упущенная периферия даёт +20 мкА.
- Для I²C/SPI/UART сначала выполните
-
После пробуждения быстро выполните задачу и снова засыпьте
- Сначала включите HSI16, выполните задачу, затем выполните DeInit периферии, переключите тактирование обратно на LSE и снова войдите в STOP2.
- Весь цикл: пробуждение → измерение → передача → сон должен занимать менее 20 мс. Средний ток: 0.8 мкА·(время сна/период) + 5 мА·0.02 с/период. Для водяного счётчика с измерением раз в час среднее потребление 3 мкА.
-
Советы по измерению тока
- Используйте uCurrent Gold или Agilent 34401A, включив их в цепь 3.3 В. Не используйте миллиамперный режим мультиметра — его внутреннее сопротивление 1 Ом может добавить 100 мкА.
- Сначала запрограммируйте «голую» плату без периферии. Увидев 0.4 мкА, постепенно добавляйте функции, проверяя ток после каждого шага. Так сразу поймёте, кто «ворует» ток.
Следуя этим семи шагам, легко добиться потребления ниже 1 мкА на L476. Важно: не ориентируйтесь на измерения ST Nucleo — там есть ST-LINK, LD3, LD4, которые добавляют около 200 мкА. Проверяйте ток только на своей плате. Удачи с первым запуском — программатор вам больше не понадобится!
Эй, L476 — это отличный чип для низкого энергопотребления, но достижение однозначных микроАмперных значений может быть сложным. Я уже сталкивался с этим раньше.
Вот список проверок, который я обычно прохожу. Почти всегда проблема в одном из этих пунктов.
1. Очевидная ловушка: Отладчик
Вы измеряете ток при подключенном отладчике ST-LINK или J-Link? Если да, немедленно отключите его.
Отладочный модуль (часть ядра ARM) остается подключенным и активным при подключенном отладчике, что не позволяет МК войти в самые глубокие режимы сна. Это может добавить 1-2 мА потребления самостоятельно.
Шаг: Залейте код, отключите отладчик, перезагрузите плату (или выполните полный цикл питания), а затем измеряйте ток.
2. Выберите правильный режим низкого энергопотребления
У L476 есть множество режимов. Не используйте простой WFI (ожидание прерывания) в режиме Sleep.
- Режим Stop 2: Обычно лучший выбор. Очень низкое энергопотребление (около 1 мкА с RTC) и сохраняет всю оперативную память и регистры. Быстрый выход из режима ожидания. Используйте
HAL_PWR_EnterSTOP2Mode(PWR_STOPENTRY_WFI). - Режим Standby: Еще更低ий уровень энергопотребления, но очищает оперативную память. Подходит только если вы можете перезапустить приложение с нуля после выхода из сна.
- Режим Shutdown: Еще ниже, но почти полное отключение питания.
Шаг: Используйте режим Stop 2 как основное состояние низкого энергопотребления.
3. Отключите ВСЕ неиспользуемые периферийные устройства
Это самая распространенная ошибка. Каждое периферийное устройство, которое вы не используете, должно иметь отключенный тактовый сигнал. Если вы оставите тактовый сигнал для таймера, UART, I2C, SPI, ADC, USB и т.д., оно будет потреблять энергию.
Шаг:
- Используйте CubeMX и пройдитесь по списку периферийных устройств. Отключите все, что не нужно.
- В своем коде перед входом в сон вручную отключите тактовые сигналы для периферийных устройств, которые вы использовали, но не нужны во время сна.
- Пример:
__HAL_RCC_USART1_CLK_DISABLE();__HAL_RCC_TIM2_CLK_DISABLE();
4. Правильно настройте GPIO
Плавающие выводы — катастрофа для низкого энергопотребления. Они могут находиться на промежуточном напряжении, вызывая колебания входного буфера и потребление тока.
Шаг: Все неиспользуемые выводы МК должны быть настроены как Аналоговый вход без подтяжки вверх или вниз. Это их состояние с минимальным энергопотреблением.
- В CubeMX найдите все неиспользуемые выводы (зеленые) и установите их в
GPIO_Analog. - Для выводов, подключенных к внешним компонентам, убедитесь, что они не плавающие. Если кнопка имеет внешнюю подтяжку, она потребляет ток.
5. Снизьте системную частоту (перед сном)
Вам не нужно работать на 80 МГц, если вы собираетесь спать. Высокая частота потребляет больше энергии.
Шаг: Перед вызовом функции HAL_PWR_EnterSTOP2Mode переключите системную частоту (SYSCLK) на низкоскоростную, например MSI (например, 4 МГц или 1 МГц). При выходе из сна МК можно перенастроить PLL и вернуться к высокой частоте, если это необходимо.
6. Установите масштабирование напряжения
Серия L4 может работать с разными напряжениями ядра. Меньше напряжение = меньше энергопотребление. Это называется “диапазон”.
- Диапазон 1 (Высокая производительность): До 80 МГц.
- Диапазон 2 (Средний): До 26 МГц. Меньше энергопотребление.
- Диапазон 3 (Низкое энергопотребление): До 2 МГц. Очень низкое энергопотребление (но нельзя входить в режимы Stop из этого диапазона, поэтому Диапазон 2 обычно целевой для низкого энергопотребления в режиме работы).
Шаг: Перед сном установите Диапазон 2 (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2)). Функция HAL_PWR_EnterSTOP2Mode обычно это делает, но знать об этом полезно.
7. Проверьте свою аппаратную часть!
Включен ли светодиод? Регулятор напряжения с высоким током покоя (Iq)? Подтягивающий резистор, который всегда потребляет ток?
Шаг: Посмотрите на схему. Ваш STM32 может быть на уровне 2 мкА, но светодиод и плохой регулятор потребляют 5 мА. Используйте мультиметр, чтобы “пройтись” по плате и найти, где уходит ток.
Краткий план действий
-
Используйте CubeMX для генерации нового, чистого проекта.
-
В CubeMX:
- Установите все неиспользуемые выводы в Аналоговый режим.
- Отключите все периферийные устройства, которые не нужны (USB, ADC, DAC и т.д.).
- Включите RTC, если нужен источник пробуждения.
-
В вашем
main.c, в циклеwhile(1), добавьте этот код:/* Это просто пример, например, для 10-секундного сна */ HAL_Delay(1000); // Подождите секунду для стабилизации /* --- Подготовка ко сну --- */ // 1. Отключите активные периферийные устройства (например, UART) // __HAL_RCC_USART1_CLK_DISABLE(); // 2. Переключитесь на низкочастотный тактовый сигнал (опционально, но хорошо) // (Эта часть сложна, CubeMX может настроить тактовый сигнал пробуждения) /* --- Вход в режим Stop 2 --- */ HAL_PWR_EnterSTOP2Mode(PWR_STOPENTRY_WFI); /* --- ПРОБУЖДЕНИЕ --- */ // Системная частота будет сброшена на MSI (или HSI) // Вам нужно перенастроить тактовые сигналы, если использовали PLL // SystemClock_Config(); // Снова вызовите функцию настройки тактовых сигналов // 4. Включите периферийные устройства, которые нужны // __HAL_RCC_USART1_CLK_ENABLE(); -
Залейте этот код.
-
ОТКЛЮЧИТЕ ОТЛАДЧИК.
-
Выполните полный цикл питания платы.
-
Измерьте ток.
Вы должны увидеть резкое снижение потребления. Удачи! Сообщите, что вы найдете.