Перейти к содержанию

Почему STM32L0 сразу просыпается из режима Standby?

Обновлено Редакция GAW

В Standby у STM32L0 отключается ядро и пропадает содержимое ОЗУ, а выход из режима — это сброс: программа начинается сначала, а флаг SBF подсказывает, что был сон (термин «Режим Standby»). Если же микроконтроллер «просыпается» мгновенно, причина почти всегда в условиях входа из табл. 40 RM0377.

Условия входа и типичные ошибки

Условие по RM0377ОшибкаРезультат
WUF = 0флаг остался от прошлого событияStandby не наступает или сразу выход
Флаг источника RTC сброшенвисит ALRAF или WUTFто же
EWUPx включают при низком уровне на WKUPвключили при высокомдополнительное событие, мгновенный выход
PDDS = 1 и SLEEPDEEP = 1PDDS = 0вместо Standby — Stop

Важная тонкость — порядок. Бит CWUF сбрасывает WUF не сразу, а через два такта системной частоты, а включение EWUPx при высоком уровне на выводе тут же ставит WUF снова. Поэтому вывод пробуждения включают раньше, чем сбрасывают флаг:

// Standby entry order for STM32L0 (RM0377, 6.3.10, 6.4.1, 6.4.2)
while (GPIOA->IDR & GPIO_IDR_ID0) { }   // WKUP pin must be low first
PWR->CSR |= PWR_CSR_EWUP1;               // enable wakeup pin
PWR->CR  |= PWR_CR_CWUF | PWR_CR_PDDS;   // clear WUF, select Standby
(void)PWR->CR;                           // let CWUF take effect
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();

Какой вывод корпуса соответствует WKUP1–WKUP3, указано в даташите конкретного STM32L0; в примере взят PA0, проверьте его для своей микросхемы. Если пробуждение идёт от RTC, перед входом сбрасывают флаг будильника или таймера пробуждения в RTC_ISR.

Как отличить причины

Поставьте в начало main() чтение флагов. SBF в PWR_CSR показывает, что Standby действительно был. Источник пробуждения показывает WUF в том же PWR_CSR — регистр не сбрасывается при выходе из Standby, — а для RTC уточняют флаг в RTC_ISR: будильник, таймер пробуждения, tamper или метка времени. Флаги сброса в RCC_CSR говорят только о причине сброса, например вывод NRST или IWDG (термин «Флаги сброса»). Если SBF = 0, вход в Standby был проигнорирован, и программа после WFI просто пошла дальше. Если для задачи достаточно сохранить ОЗУ, проще использовать Stop — что мешает низкому току там, разобрано в ответе «Почему STM32L0 потребляет много тока в Stop». Обзор семейства — на странице STM32L0.

Похожие вопросы

Как программа узнаёт, что проснулась из Standby?

По флагу SBF в PWR_CSR: его ставит аппаратура, а сбрасывает только сброс по питанию или запись бита CSBF. Проверьте SBF в начале main(), примите решение и сбросьте флаг, иначе после обычного сброса кнопкой программа решит, что снова вышла из Standby.

Почему после пробуждения бит EWUP1 снова равен нулю?

Выход из Standby — это системный сброс, а EWUPx по RM0377 сбрасываются системным сбросом. Поэтому вывод пробуждения включают заново перед каждым входом в Standby.

Можно ли разбудить STM32L0 из Standby спадом на выводе?

Выводы WKUP у STM32L0 реагируют только на нарастающий фронт: с битом EWUPx вывод подтягивается к земле, и пробуждает переход в высокий уровень. Для кнопки, замыкающей на землю, нужна инверсия снаружи или другой источник пробуждения, например RTC.

Источники

  1. STMicroelectronics. RM0377 Reference manual: Ultra-low-power STM32L0x1 advanced Arm-based 32-bit MCUs, Rev 10 — разд. 6.3.10: в Standby выводы в высокоимпедансном состоянии, кроме сброса, WKUP1–WKUP3 и выводов RTC; выход — сброс NRST, сброс IWDG, нарастающий фронт на WKUP, будильник, tamper, метка времени RTC; после выхода программа стартует как после сброса, флаг SBF показывает Standby; табл. 40: вход при SLEEPDEEP = 1, PDDS = 1, WUF = 0 и сброшенном флаге источника RTC; разд. 6.4.1: CWUF сбрасывает WUF через 2 такта системной частоты, CSBF сбрасывает SBF; разд. 6.4.2: EWUP1–EWUP3 (биты 8–10) переводят вывод в режим входа с подтяжкой к земле, сбрасываются системным сбросом; WUF ставится по выводу WKUP и по событиям RTC (будильник, tamper, метка времени, таймер пробуждения), PWR_CSR не сбрасывается при выходе из Standby; примечание к WUF: если EWUPx включают при высоком уровне на WKUP, детектируется дополнительное событие пробуждения
  2. STMicroelectronics. cmsis-device-l0, Include/stm32l053xx.h (commit 7b7ae8c) — PWR_CR_PDDS — бит 1, PWR_CR_CWUF — бит 2, PWR_CR_CSBF — бит 3; PWR_CSR_WUF — бит 0, PWR_CSR_SBF — бит 1, PWR_CSR_EWUP1 — бит 8

Нашли ошибку?